Skip to content

Commit

Permalink
Add Require#onInvalidate
Browse files Browse the repository at this point in the history
Signed-off-by: William So <polyipseity@gmail.com>
  • Loading branch information
polyipseity committed Sep 29, 2023
1 parent de069e6 commit 24dfc8d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-rats-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"obsidian-modules": minor
---

Add `Require#onInvalidate`.
5 changes: 5 additions & 0 deletions sources/@types/obsidian-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ declare module "obsidian-modules" {
*/
readonly invalidateAll: () => AsyncOrSync<void>

/**
* Module invalidation event.
*/
readonly onInvalidate: EventEmitterLite<readonly [id: string]>

/**
* Object for resolving module specifiers.
*/
Expand Down
28 changes: 21 additions & 7 deletions sources/require/require.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "./resolve.js"
import {
type AnyObject,
EventEmitterLite,
Functions,
activeSelf,
addCommand,
Expand Down Expand Up @@ -97,12 +98,13 @@ function createRequire(
ctx: ModulesPlugin,
self0: typeof globalThis,
resolve: Resolve,
oldRequire?: Require,
sourceRoot = "",
): Require {
function invalidate(self2: Require, id: string): void {
async function invalidate(self2: Require, id: string): Promise<void> {
const { aliased, aliases, cache, dependants, dependencies } = self2,
id2 = aliased.get(id) ?? id,
seen = new Set(),
seen = new Set<string>(),
ing = [...aliases.get(id2) ?? [id2]]
for (let cur = ing.shift(); cur !== void 0; cur = ing.shift()) {
if (seen.has(cur)) { continue }
Expand All @@ -117,6 +119,8 @@ function createRequire(
ing.push(...aliases.get(dep) ?? [dep])
}
}
await Promise.all([...seen]
.map(async seen2 => self2.onInvalidate.emit(seen2)))
}
function resolve0(
self2: Require,
Expand All @@ -135,7 +139,7 @@ function createRequire(
})()).add(id)
if (oldID !== void 0 && id2 !== oldID) {
aliases.get(oldID)?.delete(id)
invalidate(self2, id)
invalidate(self2, id).catch(error => { self0.console.error(error) })
}
if (resolved.cache === false) { cache.delete(id2) }
return [
Expand Down Expand Up @@ -487,21 +491,25 @@ function createRequire(
}
},
async invalidate(id: string) {
invalidate(ret, id)
await invalidate(ret, id)
await resolve.invalidate(id)
},
async invalidateAll() {
const { aliased, aliases, cache, dependants, dependencies } = ret
const { aliased, aliases, cache, dependants, dependencies } = ret,
ids = [...cache.keys()]
clearProperties(cache)
clearProperties(dependants)
clearProperties(dependencies)
clearProperties(aliased)
clearProperties(aliases)
await Promise.all(ids.map(async id => ret.onInvalidate.emit(id)))
await resolve.invalidateAll()
},
onInvalidate: oldRequire?.onInvalidate ??
new EventEmitterLite<readonly [id: string]>(),
resolve,
})
resolve.onInvalidate.listen(id => { invalidate(ret, id) })
resolve.onInvalidate.listen(async id => invalidate(ret, id))
return ret
}

Expand Down Expand Up @@ -538,7 +546,13 @@ function createAndSetRequire(
resolve: Resolve,
): () => void {
const { api: { requires }, manifest: { id } } = context,
req = createRequire(context, self0, resolve, `plugin:${id}`)
req = createRequire(
context,
self0,
resolve,
requires.get(self0),
`plugin:${id}`,
)
requires.set(self0, req)
if (name in self0 || name === "require") {
return around(self0, {
Expand Down

0 comments on commit 24dfc8d

Please sign in to comment.