@haverstack/core 0.11.1 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/access.d.ts CHANGED
@@ -6,7 +6,8 @@
6
6
  * storage backend. Used by ScopedStack (see stack.ts) to enforce access
7
7
  * control; exported standalone for callers that want the raw predicate.
8
8
  */
9
- import type { Association, EntityId, RecordId, StackRecord } from './types.js';
9
+ import type { Association, EntityId, Permission, RecordId, StackRecord } from './types.js';
10
+ import type { ValidationError } from './validate.js';
10
11
  export type AccessMode = 'read' | 'write';
11
12
  /** An entity's standing within a `_group` Record's roster. `admin` implies `member` for ACL purposes. */
12
13
  export type GroupRole = 'member' | 'admin';
@@ -28,6 +29,13 @@ export type RecordResolver = (id: RecordId) => Promise<StackRecord | null>;
28
29
  * subject.
29
30
  */
30
31
  export declare function checkAccess(record: StackRecord, subjectEntityId: EntityId | null, ownerEntityId: EntityId | null, mode: AccessMode, resolveRecord: RecordResolver): Promise<boolean>;
32
+ /**
33
+ * Rejects permission entries that convey write without read — the shape
34
+ * entryConveys() refuses to honor, caught at the point of storage so an
35
+ * owner writing one is told rather than left with a bit that does nothing.
36
+ * See docs/spec/access-control.md § Write implies read.
37
+ */
38
+ export declare function validatePermissions(permissions: Permission[] | undefined, path?: string): ValidationError[];
31
39
  /**
32
40
  * Determine an entity's role within a `_group` Record's roster from its
33
41
  * relationship associations. `admin` short-circuits — it's strictly more
@@ -1 +1 @@
1
- {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,yGAAyG;AACzG,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAE3E;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,eAAe,EAAE,QAAQ,GAAG,IAAI,EAChC,aAAa,EAAE,QAAQ,GAAG,IAAI,EAC9B,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAAC,OAAO,CAAC,CA4BlB;AAYD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,EACvC,QAAQ,EAAE,QAAQ,GACjB,SAAS,GAAG,IAAI,CASlB"}
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,yGAAyG;AACzG,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAE3E;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,eAAe,EAAE,QAAQ,GAAG,IAAI,EAChC,aAAa,EAAE,QAAQ,GAAG,IAAI,EAC9B,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAAC,OAAO,CAAC,CAwBlB;AAeD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,UAAU,EAAE,GAAG,SAAS,EACrC,IAAI,SAAgB,GACnB,eAAe,EAAE,CAanB;AAYD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,EACvC,QAAQ,EAAE,QAAQ,GACjB,SAAS,GAAG,IAAI,CASlB"}
package/dist/access.js CHANGED
@@ -30,24 +30,50 @@ export async function checkAccess(record, subjectEntityId, ownerEntityId, mode,
30
30
  if (p.access === 'public' && mode === 'read')
31
31
  return true;
32
32
  if (p.access === 'entity' && p.entityId === subjectEntityId) {
33
- if (mode === 'read' && p.read)
34
- return true;
35
- if (mode === 'write' && p.write)
33
+ if (entryConveys(p, mode))
36
34
  return true;
37
35
  }
38
36
  if (p.access === 'group' && subjectEntityId) {
39
37
  const role = await resolveGroupRole(p.groupId, subjectEntityId, resolveRecord);
40
38
  const satisfiesRole = p.role === 'admin' ? role === 'admin' : role !== null;
41
- if (satisfiesRole) {
42
- if (mode === 'read' && p.read)
43
- return true;
44
- if (mode === 'write' && p.write)
45
- return true;
46
- }
39
+ if (satisfiesRole && entryConveys(p, mode))
40
+ return true;
47
41
  }
48
42
  }
49
43
  return false;
50
44
  }
45
+ /**
46
+ * Whether an entry the requester already matches conveys `mode`. The write
47
+ * bit is inert without read alongside it: the mutate surface hands back the
48
+ * record it wrote and opens its whole history, so a write bit without read
49
+ * would disclose exactly what withholding read asks to withhold. Refused at
50
+ * the write by validatePermissions() and again here, since a `permissions`
51
+ * array can also arrive from an import or a foreign server. See
52
+ * docs/spec/access-control.md § Write implies read.
53
+ */
54
+ function entryConveys(p, mode) {
55
+ return mode === 'read' ? p.read : p.write && p.read;
56
+ }
57
+ /**
58
+ * Rejects permission entries that convey write without read — the shape
59
+ * entryConveys() refuses to honor, caught at the point of storage so an
60
+ * owner writing one is told rather than left with a bit that does nothing.
61
+ * See docs/spec/access-control.md § Write implies read.
62
+ */
63
+ export function validatePermissions(permissions, path = 'permissions') {
64
+ const errors = [];
65
+ (permissions ?? []).forEach((p, i) => {
66
+ if (p.access === 'public')
67
+ return;
68
+ if (p.write && !p.read) {
69
+ errors.push({
70
+ path: `${path}[${i}]`,
71
+ message: 'write requires read: a write-holder reaches the record and its history through the mutate surface, so `write: true, read: false` withholds nothing',
72
+ });
73
+ }
74
+ });
75
+ return errors;
76
+ }
51
77
  async function resolveGroupRole(groupRecordId, entityId, resolveRecord) {
52
78
  const group = await resolveRecord(groupRecordId);
53
79
  if (!group)
@@ -1 +1 @@
1
- {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAmB,EACnB,eAAgC,EAChC,aAA8B,EAC9B,IAAgB,EAChB,aAA6B;IAE7B,gCAAgC;IAChC,IAAI,eAAe,IAAI,eAAe,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IAEtE,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;IAEjC,4BAA4B;IAC5B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAE1D,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;YAC5D,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC3C,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,eAAe,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;YAC/E,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;YAC5E,IAAI,aAAa,EAAE,CAAC;gBAClB,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAC;gBAC3C,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,KAAK;oBAAE,OAAO,IAAI,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,aAAuB,EACvB,QAAkB,EAClB,aAA6B;IAE7B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,yBAAyB,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,YAAuC,EACvC,QAAkB;IAElB,IAAI,IAAI,GAAqB,IAAI,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACzD,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO;gBAAE,OAAO,OAAO,CAAC;YACxC,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ;gBAAE,IAAI,GAAG,QAAQ,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Stack — Change Events
3
+ * -------------------------------------------------------
4
+ * The emitter behind StackClient.subscribe(): a subscriber registry, the
5
+ * filter predicate, and the projection that turns what the emitter knows
6
+ * into what a subscriber is allowed to see.
7
+ *
8
+ * The split between those last two is the point of this module. Emission
9
+ * always carries the record — a permission filter has nothing to decide
10
+ * with otherwise, and on a hard delete there is nothing left to fetch —
11
+ * while the frame handed to a handler is projected from it. So the rule
12
+ * that a purge discloses neither the record nor its provenance is a
13
+ * property of one function here, not a convention every emission site has
14
+ * to remember. See docs/spec/events.md.
15
+ */
16
+ import type { ChangeActor, ChangeFilter, ChangeKind, ChangeOp, RecordChange, StackRecord, SubscribeOptions, Unsubscribe } from './types.js';
17
+ /**
18
+ * What the emitter knows: the envelope, plus the record it describes.
19
+ * `record` is the filtering input and is never delivered unprojected —
20
+ * emitted() is the only way out.
21
+ */
22
+ export type EmittedChange = {
23
+ change: Omit<RecordChange, 'record'>;
24
+ /**
25
+ * The record as of the change; for `purged`, as it stood immediately
26
+ * before destruction. Present for every emission, including the ones
27
+ * whose frames must not carry it.
28
+ */
29
+ record: StackRecord;
30
+ };
31
+ /**
32
+ * Whether an emission matches a subscription's filter. Reads the record
33
+ * for the fields the envelope deliberately omits, so `entityId` filters on
34
+ * the author and `purged` frames stay filterable without carrying either.
35
+ */
36
+ export declare function matchesFilter(emitted: EmittedChange, filter?: ChangeFilter): boolean;
37
+ /**
38
+ * The frame a subscriber receives. A `purged` frame never carries the
39
+ * record, whatever was asked for: hard delete is the erasure primitive,
40
+ * and a frame that shipped the body — or the author — of a record the
41
+ * stack has just destroyed would hand every subscriber a permanent copy of
42
+ * the thing being erased. See docs/spec/events.md § Purged records carry
43
+ * nothing.
44
+ *
45
+ * The record rides by reference, shared across every frame projected from
46
+ * one emission: handlers are contractually read-only over it, and copying
47
+ * per subscriber would charge every consumer for a defect none of them
48
+ * have. See docs/spec/events.md § The event shape.
49
+ */
50
+ export declare function emitted(emission: EmittedChange, includeRecords: boolean): RecordChange;
51
+ /**
52
+ * One subscription's delivery. Subclassed rather than parameterized
53
+ * because the two deliveries differ in kind: an unscoped subscriber is
54
+ * handed the frame inline, while a scoped one has an async permission
55
+ * decision to make first.
56
+ */
57
+ export declare abstract class Subscription {
58
+ protected readonly handler: (change: RecordChange) => void;
59
+ protected readonly opts: SubscribeOptions;
60
+ private closed;
61
+ constructor(handler: (change: RecordChange) => void, opts: SubscribeOptions);
62
+ /** Called by the emitter for every change, filtered or not. */
63
+ abstract accept(emission: EmittedChange): void;
64
+ get isClosed(): boolean;
65
+ close(): void;
66
+ /**
67
+ * Hand a frame to the handler. A handler that throws cannot fail the
68
+ * write it is being told about — the write is already durable — so the
69
+ * error goes to onError, or is rethrown asynchronously so that it
70
+ * surfaces as an unhandled error rather than vanishing.
71
+ */
72
+ protected deliver(emission: EmittedChange): void;
73
+ protected reportError(err: unknown): void;
74
+ }
75
+ /**
76
+ * Assemble what the emitter knows about one mutation.
77
+ *
78
+ * The actor is read off the record for every version-bumping op, because
79
+ * `updatedBy`/`updatedVia` were stamped by that same write and so agree
80
+ * with what was persisted by construction. Hard delete stamps nothing and
81
+ * leaves nothing to read, so its actor is the requester, passed in. A
82
+ * purge also drops `parentId` and the create-time `appId`: the frame says
83
+ * that a record of some type was destroyed, and nothing further about
84
+ * whose it was. See docs/spec/events.md § Purged records carry nothing.
85
+ */
86
+ export declare function buildEmission(op: ChangeOp, record: StackRecord, opts?: {
87
+ actor?: ChangeActor;
88
+ at?: Date;
89
+ }): EmittedChange;
90
+ /**
91
+ * The subscriber registry. One per `Stack`; `ScopedStack` filters the same
92
+ * stream rather than opening its own, so a scoped view can never observe a
93
+ * change the stack did not emit.
94
+ */
95
+ export declare class ChangeEmitter {
96
+ private readonly subscriptions;
97
+ emit(emission: EmittedChange): void;
98
+ add(subscription: Subscription): Unsubscribe;
99
+ subscribe(handler: (change: RecordChange) => void, opts: SubscribeOptions): Unsubscribe;
100
+ /** Ends every subscription — a closed stack emits nothing further. */
101
+ closeAll(): void;
102
+ }
103
+ /** The kind each op produces. See docs/spec/events.md § The event shape. */
104
+ export declare const CHANGE_KINDS: Record<ChangeOp, ChangeKind>;
105
+ //# sourceMappingURL=changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACrC;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAKF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAoBpF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,GAAG,YAAY,CAItF;AAED;;;;;GAKG;AACH,8BAAsB,YAAY;IAI9B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI;IAC1D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB;IAJ3C,OAAO,CAAC,MAAM,CAAS;gBAGF,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,EACvC,IAAI,EAAE,gBAAgB;IAG3C,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAE9C,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAShD,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;CAc1C;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC;IAAC,EAAE,CAAC,EAAE,IAAI,CAAA;CAAO,GAC5C,aAAa,CAgCf;AAiBD;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IAEzD,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAQnC,GAAG,CAAC,YAAY,EAAE,YAAY,GAAG,WAAW;IAQ5C,SAAS,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,EAAE,IAAI,EAAE,gBAAgB,GAAG,WAAW;IAIvF,sEAAsE;IACtE,QAAQ,IAAI,IAAI;CAIjB;AAED,4EAA4E;AAC5E,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAWrD,CAAC"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Stack — Change Events
3
+ * -------------------------------------------------------
4
+ * The emitter behind StackClient.subscribe(): a subscriber registry, the
5
+ * filter predicate, and the projection that turns what the emitter knows
6
+ * into what a subscriber is allowed to see.
7
+ *
8
+ * The split between those last two is the point of this module. Emission
9
+ * always carries the record — a permission filter has nothing to decide
10
+ * with otherwise, and on a hard delete there is nothing left to fetch —
11
+ * while the frame handed to a handler is projected from it. So the rule
12
+ * that a purge discloses neither the record nor its provenance is a
13
+ * property of one function here, not a convention every emission site has
14
+ * to remember. See docs/spec/events.md.
15
+ */
16
+ /** The `baseId@version` split, as grants and query filters read it. */
17
+ const baseIdOf = (typeId) => typeId.split('@')[0];
18
+ /**
19
+ * Whether an emission matches a subscription's filter. Reads the record
20
+ * for the fields the envelope deliberately omits, so `entityId` filters on
21
+ * the author and `purged` frames stay filterable without carrying either.
22
+ */
23
+ export function matchesFilter(emitted, filter) {
24
+ if (!filter)
25
+ return true;
26
+ const { change, record } = emitted;
27
+ if (filter.kinds && !filter.kinds.includes(change.kind))
28
+ return false;
29
+ if (filter.typeId !== undefined) {
30
+ const wanted = Array.isArray(filter.typeId) ? filter.typeId : [filter.typeId];
31
+ const family = baseIdOf(change.typeId);
32
+ if (!wanted.some((t) => baseIdOf(t) === family))
33
+ return false;
34
+ }
35
+ if (filter.parentId !== undefined) {
36
+ const parentId = record.parentId ?? null;
37
+ if (parentId !== filter.parentId)
38
+ return false;
39
+ }
40
+ if (filter.entityId !== undefined && record.entityId !== filter.entityId)
41
+ return false;
42
+ return true;
43
+ }
44
+ /**
45
+ * The frame a subscriber receives. A `purged` frame never carries the
46
+ * record, whatever was asked for: hard delete is the erasure primitive,
47
+ * and a frame that shipped the body — or the author — of a record the
48
+ * stack has just destroyed would hand every subscriber a permanent copy of
49
+ * the thing being erased. See docs/spec/events.md § Purged records carry
50
+ * nothing.
51
+ *
52
+ * The record rides by reference, shared across every frame projected from
53
+ * one emission: handlers are contractually read-only over it, and copying
54
+ * per subscriber would charge every consumer for a defect none of them
55
+ * have. See docs/spec/events.md § The event shape.
56
+ */
57
+ export function emitted(emission, includeRecords) {
58
+ const { change, record } = emission;
59
+ if (change.kind === 'purged' || !includeRecords)
60
+ return { ...change };
61
+ return { ...change, record };
62
+ }
63
+ /**
64
+ * One subscription's delivery. Subclassed rather than parameterized
65
+ * because the two deliveries differ in kind: an unscoped subscriber is
66
+ * handed the frame inline, while a scoped one has an async permission
67
+ * decision to make first.
68
+ */
69
+ export class Subscription {
70
+ handler;
71
+ opts;
72
+ closed = false;
73
+ constructor(handler, opts) {
74
+ this.handler = handler;
75
+ this.opts = opts;
76
+ }
77
+ get isClosed() {
78
+ return this.closed;
79
+ }
80
+ close() {
81
+ this.closed = true;
82
+ }
83
+ /**
84
+ * Hand a frame to the handler. A handler that throws cannot fail the
85
+ * write it is being told about — the write is already durable — so the
86
+ * error goes to onError, or is rethrown asynchronously so that it
87
+ * surfaces as an unhandled error rather than vanishing.
88
+ */
89
+ deliver(emission) {
90
+ if (this.closed)
91
+ return;
92
+ try {
93
+ this.handler(emitted(emission, this.opts.includeRecords === true));
94
+ }
95
+ catch (err) {
96
+ this.reportError(err);
97
+ }
98
+ }
99
+ reportError(err) {
100
+ if (this.opts.onError) {
101
+ try {
102
+ this.opts.onError(err);
103
+ }
104
+ catch {
105
+ // An onError that throws has nowhere left to report to. Losing it
106
+ // is better than letting it escape into a mutation's call stack.
107
+ }
108
+ return;
109
+ }
110
+ queueMicrotask(() => {
111
+ throw err;
112
+ });
113
+ }
114
+ }
115
+ /**
116
+ * Delivery with no permission boundary: `Stack` is the unscoped layer, so
117
+ * a subscriber there already reaches every record by other means.
118
+ */
119
+ class UnscopedSubscription extends Subscription {
120
+ accept(emission) {
121
+ if (!matchesFilter(emission, this.opts.filter))
122
+ return;
123
+ this.deliver(emission);
124
+ }
125
+ }
126
+ /**
127
+ * Assemble what the emitter knows about one mutation.
128
+ *
129
+ * The actor is read off the record for every version-bumping op, because
130
+ * `updatedBy`/`updatedVia` were stamped by that same write and so agree
131
+ * with what was persisted by construction. Hard delete stamps nothing and
132
+ * leaves nothing to read, so its actor is the requester, passed in. A
133
+ * purge also drops `parentId` and the create-time `appId`: the frame says
134
+ * that a record of some type was destroyed, and nothing further about
135
+ * whose it was. See docs/spec/events.md § Purged records carry nothing.
136
+ */
137
+ export function buildEmission(op, record, opts = {}) {
138
+ const kind = CHANGE_KINDS[op];
139
+ if (kind === 'purged') {
140
+ return {
141
+ record,
142
+ change: {
143
+ kind,
144
+ op,
145
+ recordId: record.id,
146
+ typeId: record.typeId,
147
+ version: record.version,
148
+ updatedAt: opts.at ?? new Date(),
149
+ ...(opts.actor && { actor: opts.actor }),
150
+ },
151
+ };
152
+ }
153
+ const actor = actorOf(record, kind);
154
+ return {
155
+ record,
156
+ change: {
157
+ kind,
158
+ op,
159
+ recordId: record.id,
160
+ typeId: record.typeId,
161
+ version: record.version,
162
+ updatedAt: record.updatedAt,
163
+ ...(record.parentId !== undefined && { parentId: record.parentId }),
164
+ ...(actor && { actor }),
165
+ },
166
+ };
167
+ }
168
+ /**
169
+ * The acting identity a stored record reports. `appId` rides along only on
170
+ * a create, the one mutation where the record's app and the acting app are
171
+ * the same fact — on any later version it is the *creating* app, which
172
+ * describes the record rather than the change.
173
+ */
174
+ function actorOf(record, kind) {
175
+ if (!record.updatedBy)
176
+ return undefined;
177
+ return {
178
+ entityId: record.updatedBy,
179
+ ...(record.updatedVia !== undefined && { principalId: record.updatedVia }),
180
+ ...(kind === 'created' && record.appId !== undefined && { appId: record.appId }),
181
+ };
182
+ }
183
+ /**
184
+ * The subscriber registry. One per `Stack`; `ScopedStack` filters the same
185
+ * stream rather than opening its own, so a scoped view can never observe a
186
+ * change the stack did not emit.
187
+ */
188
+ export class ChangeEmitter {
189
+ subscriptions = new Set();
190
+ emit(emission) {
191
+ // Snapshotted: a handler may subscribe or unsubscribe while this loop
192
+ // runs, and neither should be seen by the emission already in flight.
193
+ for (const subscription of [...this.subscriptions]) {
194
+ if (!subscription.isClosed)
195
+ subscription.accept(emission);
196
+ }
197
+ }
198
+ add(subscription) {
199
+ this.subscriptions.add(subscription);
200
+ return () => {
201
+ subscription.close();
202
+ this.subscriptions.delete(subscription);
203
+ };
204
+ }
205
+ subscribe(handler, opts) {
206
+ return this.add(new UnscopedSubscription(handler, opts));
207
+ }
208
+ /** Ends every subscription — a closed stack emits nothing further. */
209
+ closeAll() {
210
+ for (const subscription of this.subscriptions)
211
+ subscription.close();
212
+ this.subscriptions.clear();
213
+ }
214
+ }
215
+ /** The kind each op produces. See docs/spec/events.md § The event shape. */
216
+ export const CHANGE_KINDS = {
217
+ create: 'created',
218
+ update: 'changed',
219
+ associate: 'changed',
220
+ dissociate: 'changed',
221
+ permissions: 'changed',
222
+ migrate: 'changed',
223
+ restore: 'changed',
224
+ undelete: 'changed',
225
+ delete: 'deleted',
226
+ 'hard-delete': 'purged',
227
+ };
228
+ //# sourceMappingURL=changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changes.js","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  */
17
17
  export { Stack, ScopedStack, StackError, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, StackConflictError, StackVersionConflictError, StackQueryError, StackSchemaDriftError, StackPayloadTooLargeError, StackTimeoutError, StackClosedError, } from './stack.js';
18
18
  export type { StackErrorCode, StackClient, CreateRecordOptions, StackOptions, GetRecordOptions, DeleteRecordOptions, IfVersionOptions, CollectAttachmentGarbageOptions, CollectAttachmentGarbageResult, } from './stack.js';
19
- export type { RecordId, TypeId, FileId, EntityId, AttachmentContent, StackRecord, RecordVersion, StackType, TypeSchema, FieldDef, ScalarFieldDef, ArrayFieldDef, ObjectFieldDef, ScalarFieldKind, Association, TagAssociation, AttachmentAssociation, RelationshipAssociation, Permission, StackQuery, RecordFilter, QuerySort, QueryResult, DateRange, Migration, MigrationFn, StackAdapter, StackFeatures, TokenSession, EntityContent, AppContent, GroupContent, GrantAction, GrantContent, ConfigContent, } from './types.js';
19
+ export type { RecordId, TypeId, FileId, EntityId, AttachmentContent, StackRecord, RecordVersion, ActorOptions, ChangeKind, ChangeOp, ChangeActor, RecordChange, ChangeFilter, SubscribeOptions, Unsubscribe, ExpectedVersionOptions, SnapshotOptions, StackType, TypeSchema, FieldDef, ScalarFieldDef, ArrayFieldDef, ObjectFieldDef, ScalarFieldKind, Association, TagAssociation, AttachmentAssociation, RelationshipAssociation, Permission, StackQuery, RecordFilter, QuerySort, QueryResult, DateRange, Migration, MigrationFn, StackAdapter, StackFeatures, TokenSession, EntityContent, AppContent, GroupContent, GrantAction, GrantContent, ConfigContent, } from './types.js';
20
20
  export { SYSTEM_TYPES } from './types.js';
21
21
  export { generateId } from './id.js';
22
22
  export { hashSchema, isCompatible } from './schema.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,SAAS,EACT,UAAU,EACV,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,kCAAkC;AAClC,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAoDpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,YAAY;AAEZ,4EAA4E;AAC5E,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,kCAAkC;AAClC,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AA8DpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,YAAY;AAEZ,4EAA4E;AAC5E,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}