feat(events): WrappingSet.on/off with mapped values#93
Draft
jeswr wants to merge 1 commit into
Draft
Conversation
Adds change subscriptions at the collection level: WrappingSet.on(listener) filters the underlying dataset's add/delete quad events by this set's subject and predicate and projects the affected quad's object through the set's termAs mapping before invoking the listener. off(listener) detaches via a WeakMap<listener, Map<subject NUL predicate, adapter>> registry, so it works across the fresh WrappingSet instances SetFrom returns on every property access. Datasets that do not emit change events are rejected with a typed DatasetEventsError. @jeswr/eventful-dataset is a devDependency only (tests + type-only import); the published declarations do not reference it and the package keeps zero runtime dependencies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 6, 2026
Draft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Adds change subscriptions at the collection level:
WrappingSet<T>gainson(listener)/off(listener), with listeners receiving the kind of mutation and the mapped JavaScript value rather than a raw quad.WrappingSetListener<T>—(event: "add" | "delete", value: T) => void.on(listener)subscribes to the underlying dataset's"add"/"delete"quad events, filters them by this set's subject + predicate, and projects the affected quad's object through thetermAsmapping the set was created with. Mutations made through any route (the dataset directly, sibling wrappers) are observed.off(listener)detaches via aWeakMap<listener, Map<subject␀predicate, adapter>>registry, so it works across the fresh instancesSetFrom.subjectPredicatereturns on every property access (instance.prop.on(l)…instance.prop.off(l)just works). Re-attaching the same listener for the same subject + predicate replaces the previous subscription, so events are never delivered twice.DatasetEventsError(extendsWrapperError).Event-emitting datasets are detected structurally (a
DatasetCorethat is also an EventEmitter with"add"/"delete"quad events, e.g.EventfulDatasetCorefrom@jeswr/eventful-dataset). That package is a devDependency only (tests + a type-only import); the emitted declarations do not reference it and the package keeps zero runtime dependencies.Relationship to other PRs
WrappingSetlistener slice of Omnibus #73 —WrappingSetListener,WrappingSet.on/off, and the WeakMap adapter registry keyed bylistener → subject␀predicate, ported ontomainwithout the rest of the omnibus (NotificationsDatasetCoreis replaced by the structural eventful-dataset surface). Omnibus #73's set-event behaviour is covered by the ported tests intest/unit/wrapping_set_events.test.ts.WrappingSetfrommod.tsand narrowingSetFrom.subjectPredicate's return type toWrappingSet<T>); they are textually identical there, so they drop out on rebase once feat: export WrappingSet and narrow SetFrom's return type to WrappingSet<T> #92 lands. This PR is self-contained againstmaineither way.Tests
14 new tests (
test/unit/wrapping_set_events.test.ts): add/delete/clear emission with mapped values (term and literal mappings), subject/predicate filtering, direct dataset mutations, no event on ineffective adds, multiple independent listeners, live re-iteration inside a listener,offacross fresh instances / unknown listeners / per-(subject, predicate) detachment, re-subscription replacement, and theDatasetEventsErrorpath.npm test(136 tests, 0 fail),npx typedoc, andnpm audit --omit=devall pass locally.