provident-storeroom 0.1.3 → 0.2.0
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/README.md +52 -5
- package/index.d.ts +173 -13
- package/index.mjs +523 -22
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -32,20 +32,63 @@ addon's path directly is outside every clause of this contract.
|
|
|
32
32
|
|
|
33
33
|
## The surface
|
|
34
34
|
|
|
35
|
-
**The eight verbs of `surface.md §2` and NOTHING ELSE**, plus the
|
|
36
|
-
|
|
35
|
+
**The eight verbs of `surface.md §2` and NOTHING ELSE**, plus the instance `storeCreate` returned — whose own
|
|
36
|
+
member set is the FOUR the dated clause below prints:
|
|
37
37
|
|
|
38
38
|
| The member | Its answer |
|
|
39
39
|
| --- | --- |
|
|
40
|
-
| `storeCreate(cfg)` | the package's own instance handle — `cfg` carries the store's
|
|
40
|
+
| `storeCreate(cfg)` | the package's own instance handle — `cfg` carries the store's four declared keys and no fifth |
|
|
41
41
|
| `read(instance, address, tier?)` | a leaf's literal, a branch's assembled value, the empty address's whole register |
|
|
42
42
|
| `readLiteral(instance, address, tier?)` | the same, narrowed to a leaf (`ReadTargetIsBranch` on a branch) |
|
|
43
|
-
| `write(instance, address, tier, value)` | `{op, watched, triggered}` |
|
|
43
|
+
| `write(instance, address, tier, value, commit?)` | `{op, watched, triggered}` — the fifth argument OPTIONAL and declared LAST; its absence is in domain |
|
|
44
44
|
| `delete(instance, address, tier?)` | `{address, tiers, triggered}` |
|
|
45
45
|
| `rollback(instance, opId)` | `{opId, undoneOps, restoredTo}` |
|
|
46
46
|
| `listen(instance, address)` | a fresh opaque handle |
|
|
47
47
|
| `unlisten(instance, handle)` | `undefined` — and a no-op success for every value outside the domain |
|
|
48
48
|
| `instance.register(handle, listener)` | `undefined`; a non-function listener or a handle this instance never minted throws a `TypeError` |
|
|
49
|
+
| `instance.on(address, listener)` | a fresh opaque handle — the store's `listen` plus this package's own registration |
|
|
50
|
+
| `instance.off(handle)` | `undefined` — the store-side withdrawal, and this package's own registry removal |
|
|
51
|
+
| `instance.settle(record)` | `undefined` — the ordering seam: the one member THE KERNEL CALLS, and the arm that performs the `file`-tier save |
|
|
52
|
+
|
|
53
|
+
**⟶ AMENDED 2026-10-15 — THE TABLE ABOVE IS READ AT THE FOUR-KEY CONSTRUCTION, THE FOURTH OWN MEMBER AND THE
|
|
54
|
+
WRITE'S FIFTH ARGUMENT** (`surface.md §2.1`'s dated clause of 2026-10-15 and its `cfg` block; `§2.2`'s dated
|
|
55
|
+
clause of the same date and its clause 4; `§2.11`; `parameter-semantics.md §2.20` = `PAR-JS-20` and `§2.21` =
|
|
56
|
+
`PAR-JS-21`; `docs/decisions.md` · `A116`). **THE THREE CELLS IT RE-SPELLS, EACH NAMED BY ITS OWN WORDS: the
|
|
57
|
+
cells above are ALREADY RE-SPELLED IN PLACE, so the table stands in its OPERATIVE form and the as-filed wording
|
|
58
|
+
is the one NAMED here — *"the store's three declared keys and no fourth"* READS *"the store's four declared keys
|
|
59
|
+
and no fifth"*; *"plus the one member of the object `storeCreate` returned"* READS *"plus the instance
|
|
60
|
+
`storeCreate` returned — whose own member set is the FOUR printed above"*; and the `write` cell's
|
|
61
|
+
*"`write(instance, address, tier, value)`"* READS *"`write(instance, address, tier, value, commit?)`"*.**
|
|
62
|
+
|
|
63
|
+
1. **THE FOUR DECLARED KEYS, AND NO FIFTH.** **They are `filePath` · `journalLength` · `listeners` ·
|
|
64
|
+
`constraints` — `4` — each passed through WITHOUT a default, a rename or a key of the package's own, and
|
|
65
|
+
the declared arity is `4`.** **THE FOURTH IS `constraints`, OPTIONAL AND ABSENT-IN-DOMAIN like `filePath`:
|
|
66
|
+
it is the APPLICATION'S OWN constraint list, supplied at startup — and THE LIST IS NOT PERSISTED, so the
|
|
67
|
+
store writes no byte of it into the file and holds no register key for it, while at a boot over an existing
|
|
68
|
+
file the LOADED STATE is validated against the supplied list.** **AND A CALLER-SUPPLIED KEY BEYOND THE FOUR
|
|
69
|
+
IS IGNORED AND PRODUCES NO CODE** — *"no fifth"* is a constraint on the PACKAGE's own passing and never a
|
|
70
|
+
refusal of the caller's extra key (`parameter-semantics.md §2.21`; `docs/specs/storeroom-native/contract.md
|
|
71
|
+
§7.1`).
|
|
72
|
+
2. **THE INSTANCE'S OWN MEMBERS ARE FOUR: `{ register, on, off, settle }`, AND NOTHING ELSE.** **`register` is
|
|
73
|
+
the registration site; `on` and `off` are the listener members; and `settle(record) -> undefined` is THE
|
|
74
|
+
ORDERING SEAM the kernel calls at the two instants of a kernel-driven write** (`surface.md §2.1`'s dated
|
|
75
|
+
clause of 2026-10-15 (a); `§2.4` item 9; `A116` (D1)). **AND NO RELEASE VERB IS ONE OF THEM** — none of the
|
|
76
|
+
four releases the instance.
|
|
77
|
+
3. **THE WRITE'S DECLARED ARITY IS `4` REQUIRED ARGUMENTS WITH A FIFTH OPTIONAL `commit`, DECLARED LAST**, and
|
|
78
|
+
the declaration governs over the flow's own order: the `commit` is the kernel's own `{ attempt, op,
|
|
79
|
+
triggered, pending }` record — `K-2 commit`'s return — and **AN ABSENT `commit` IS IN DOMAIN**, because the
|
|
80
|
+
write opens or joins a commit all the same (`surface.md §2.2` clause 1). **THE PACKAGE READS THE CALL'S
|
|
81
|
+
ARGUMENT COUNT AT THE FIFTH POSITION AND NOWHERE ELSE** (`§2.2` clause 4): the position ABSENT proceeds, and
|
|
82
|
+
a SUPPLIED `undefined` at the position — or any other form outside the admitted one — is REFUSED, so no
|
|
83
|
+
verb is reached and no byte moves. **AND NO OTHER POSITION OF ANY VERB GAINS AN ARITY READ, A DEFAULT OR A
|
|
84
|
+
SUBSTITUTED ARGUMENT.**
|
|
85
|
+
4. **THE VERB PERFORMS NO FILE I/O ON ANY OF ITS ARMS** (`§2.11` clause 2): the durable `file`-tier save is the
|
|
86
|
+
instance's `settle` member's own act at THE TERMINAL ARM of a kernel-driven pass and ON ITS PASSING ARM
|
|
87
|
+
ALONE — constraints, then save, then the delivered listener bodies, the save first because no listener body
|
|
88
|
+
runs before it — keyed by the `op` the settled record carries. **AND THE SAVE *IS* A CONSTRAINT, EVALUATED
|
|
89
|
+
LAST: a FAILED SAVE IS AN UNREPAIRABLE CONSTRAINT VIOLATION** (`§2.11` clause 5). **WHERE THE SAVE'S ACT
|
|
90
|
+
FAILS, THE STORE ROLLS THE WRITE BACK AND THE CALLER RECEIVES THE FAILURE AFTER IT AND NEVER THE
|
|
91
|
+
ROLLED-BACK STATE**, and the package compensates for nothing (`§2.11` clauses 3 and 5).
|
|
49
92
|
|
|
50
93
|
**The failure form is ONE** (`surface.md §2.5`, `DD-12`): a THROWN plain object carrying exactly
|
|
51
94
|
`{status, message}` — never an `Error` subclass, never a returned tagged union and never a `Promise`.
|
|
@@ -61,7 +104,11 @@ session's token names no registration of this process, and `unlisten` over it is
|
|
|
61
104
|
a `file`-tier version and then constructs a fresh instance over an equal `filePath` sees the removed version
|
|
62
105
|
STAND AGAIN — that re-boot is the store's own declared boot and not a defect. And a `file`-tier `write` that
|
|
63
106
|
fails answers `FileCommitFailed` after the store's own automatic journal rollback has run; the package
|
|
64
|
-
compensates for nothing.
|
|
107
|
+
compensates for nothing. **⟶ AMENDED 2026-10-15 — THE SECOND READING'S *"a `file`-tier `write` that fails"* IS
|
|
108
|
+
RE-SPELLED IN PLACE, BECAUSE THE VERB IS NO LONGER WHAT PERFORMS THE SAVE: it READS *"a `file`-tier save that
|
|
109
|
+
fails"* — the `settle` member's terminal-arm act of the clause above — the cell above standing in that
|
|
110
|
+
operative form** (`surface.md §2.8` item 2 and `§2.11` clause 5; `parameter-semantics.md
|
|
111
|
+
§2.19`; `A116` (D3)).
|
|
65
112
|
|
|
66
113
|
## How the addon is resolved — three rungs, and the covered/uncovered answer
|
|
67
114
|
|
package/index.d.ts
CHANGED
|
@@ -8,8 +8,13 @@
|
|
|
8
8
|
//
|
|
9
9
|
// **IT DECLARES THREE THINGS AND NOTHING ELSE** (`distribution.md §5.2`): (1) the EIGHT VERBS of the
|
|
10
10
|
// claimed ESM entry, exactly as the sibling directory enumerates them and with NO ninth name; (2) the
|
|
11
|
-
// instance's own member set, `{ register, on, off }` —
|
|
12
|
-
//
|
|
11
|
+
// instance's own member set, `{ register, on, off, settle }` — FOUR own members and nothing else
|
|
12
|
+
// (`distribution.md §5.2` item 2 read with `surface.md §2.1`'s dated clause (a) and `§2.4` item 9 (f)):
|
|
13
|
+
// `register(handle, listener) -> undefined` · `on(address, listener) -> handle` · `off(handle) ->
|
|
14
|
+
// undefined` · `settle(record) -> undefined`, each with its argument types and its return, the FOURTH
|
|
15
|
+
// being THE ORDERING SEAM the kernel calls and the entry implements, and with NO fifth member and NO
|
|
16
|
+
// ninth named export for it; and (3) the failure surface, a thrown plain object with exactly
|
|
17
|
+
// `{status, message}`.
|
|
13
18
|
//
|
|
14
19
|
// **AND THE RECORDS THOSE VERBS ANSWER WITH ARE DECLARED BESIDE THEM, WHICH IS STILL PART (1) AND NOT A
|
|
15
20
|
// FOURTH THING**: `Address` · `Tier` · `TierSet` · `StoreConfig` · `BaseState` · `JournalOp` ·
|
|
@@ -19,6 +24,17 @@
|
|
|
19
24
|
// them is a STORE type**: no register, no anchor, no tier tree, no journal and no store verb is declared
|
|
20
25
|
// here (`§5.2` item 4).
|
|
21
26
|
//
|
|
27
|
+
// **AND TWO MORE SHAPES STAND BESIDE THOSE ELEVEN WITHOUT A BYTE OF EITHER BEING MINTED HERE, BECAUSE
|
|
28
|
+
// `settle`'s ONE ARGUMENT POSITION IS THE KERNEL'S OWN RECORD AND NOT THIS PACKAGE'S** (`§2.4` item 9
|
|
29
|
+
// (f)'s *"each with its argument types"* read with its *"no `pending`-shaped record type this unit does
|
|
30
|
+
// not declare"*): **`AttemptRef` (`1` member) and `CommitRecord` (`4` members — `attempt` · `op` ·
|
|
31
|
+
// `triggered` · `pending`) are THE KERNEL'S OWN NAMED SHAPES, DECLARED BY THE KERNEL AND NOT BY THIS
|
|
32
|
+
// UNIT** (`kernel-surface.md §1` item 4's closed record enumeration; its `§2.1` item 2 for the record's
|
|
33
|
+
// four members; `attempt-lifecycle.md §2.4` item 1 for the one-member `AttemptRef`) — so the seam's
|
|
34
|
+
// argument carries its own `pending` member and this file MINTS NO RECORD TYPE OF ITS OWN to carry it.
|
|
35
|
+
// **`AttemptRef` and `CommitRecord` are therefore not STORE types either, and not store records**: they
|
|
36
|
+
// are kernel-side shapes the instance's `settle` member takes, cited from their own unit's declaration.
|
|
37
|
+
//
|
|
22
38
|
// **AND THE ONE THING THIS DECLARATION MUST NOT CARRY, STATED SO THE FINDING RULE IS CHECKABLE**
|
|
23
39
|
// (`distribution.md §5.2` item 4): **it declares NO store type, NO store verb, NO `findAddress`, NO
|
|
24
40
|
// release verb and NO constraint or repair seam** — each of those is a declaration the sibling directory
|
|
@@ -51,7 +67,19 @@ export type Tier = 'mem' | 'file' | 'temp';
|
|
|
51
67
|
*/
|
|
52
68
|
export type TierSet = Tier | readonly Tier[];
|
|
53
69
|
|
|
54
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* The configuration a store is constructed from — **the store's FOUR declared keys and no FIFTH**
|
|
72
|
+
* (`filePath` · `journalLength` · `listeners` · `constraints`), each passed through WITHOUT a default, a
|
|
73
|
+
* rename or a key of this package's own.
|
|
74
|
+
*
|
|
75
|
+
* **⟶ RE-SPELLED 2026-10-15 (`surface.md §2.1`'s `cfg` block and its dated clause of 2026-10-15;
|
|
76
|
+
* `contract.md` `DD-36` as amended 2026-10-15; `parameter-semantics.md §2.21` = `PAR-JS-21`): this cell as
|
|
77
|
+
* filed read *"the store's THREE declared keys and no fourth"* and is re-spelled IN PLACE to the four-key,
|
|
78
|
+
* no-FIFTH reading — the fourth declared key is `constraints`, whose own declaration stands below, and the
|
|
79
|
+
* set's declared arity is `4`.** **NO OTHER CELL OF THIS FILE MOVES** (`distribution.md §5.2`; the entry's
|
|
80
|
+
* `8` verbs, the addon's `5`, the instance's `4` own members, the kernel's `5` and the store's `8` register
|
|
81
|
+
* rows all stand as printed).
|
|
82
|
+
*/
|
|
55
83
|
export interface StoreConfig {
|
|
56
84
|
/** The journal's declared length: a positive integer (`PAR-JS-3`). */
|
|
57
85
|
readonly journalLength: number;
|
|
@@ -68,21 +96,45 @@ export interface StoreConfig {
|
|
|
68
96
|
readonly listeners: readonly unknown[];
|
|
69
97
|
/** The file the file tier is backed by, where one is declared (`PAR-JS-2`; ABSENT is in domain). */
|
|
70
98
|
readonly filePath?: string;
|
|
99
|
+
/**
|
|
100
|
+
* **⟶ ADDED 2026-10-15 (`parameter-semantics.md §2.21`; `surface.md §2.1`'s `cfg` block dated
|
|
101
|
+
* 2026-10-15; `contract.md §8.1` #16) — THE FOURTH DECLARED KEY: THE CONSTRUCTION'S CONSTRAINT LIST**,
|
|
102
|
+
* an array of `{ address, id }` pairs (`[{ address: [key], id: 'c1' }]`).
|
|
103
|
+
*
|
|
104
|
+
* **IT IS OPTIONAL AND ITS ABSENCE IS IN DOMAIN** — *"an ABSENT `constraints` is the ordinary
|
|
105
|
+
* no-constraint store, and no default is declared for it"* — **and every element and every shape outside
|
|
106
|
+
* the list is refused at the store's own construction with ITS OWN code and ITS OWN message**, which is
|
|
107
|
+
* why the element type is the caller's own shape and not a narrowed record here.
|
|
108
|
+
*/
|
|
109
|
+
readonly constraints?: readonly { readonly address: Address; readonly id: string }[];
|
|
71
110
|
}
|
|
72
111
|
|
|
73
112
|
/**
|
|
74
113
|
* **THE STORE'S OWN CLOSED SET OF FAILURE CODES, AS THE TYPE DECLARES IT — A UNION OVER A
|
|
75
114
|
* DECLARED-BUT-OPEN SET** (`contract.md §2.4` item 2; `distribution.md §5.3`; `PUB-DD-3`).
|
|
76
115
|
*
|
|
77
|
-
* **THE
|
|
116
|
+
* **THE SIXTEEN MEMBERS BELOW ARE THE STORE'S OWN, and their membership is the STORE'S to close and
|
|
78
117
|
* never this package's**: this package MINTS NO MEMBER, WIDENS NO SET AND RENAMES NONE
|
|
79
118
|
* (`distribution.md §5.3` item 3).
|
|
80
119
|
*
|
|
81
120
|
* **AND AN UNKNOWN STATUS IS STILL TYPED — THE ESCAPE IS LOAD-BEARING, NOT A LOOSENESS.** The store's set
|
|
82
|
-
* has already moved from fourteen to fifteen
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
121
|
+
* has already moved twice: from fourteen members to fifteen, and 2026-10-15 to SIXTEEN, the sixteenth being
|
|
122
|
+
* `ConstraintListInvalid` (`contract.md §8.1` #16, amended 2026-10-15; `parameter-semantics.md §2.20` and
|
|
123
|
+
* `§2.21`). So an immutably-enumerated union would mis-type a LAWFUL refusal the moment the store's set
|
|
124
|
+
* moves (`PUB-DD-3`'s refused alternative). The `(string & {})` arm is what keeps a member the store has
|
|
125
|
+
* added typeable in an installed `0.1.0`, and its absence would be a finding rather than a strictness.
|
|
126
|
+
*
|
|
127
|
+
* **AND THE SIXTEENTH MEMBER IS DISCOVERABLE HERE AND NOT MERELY TYPEABLE**: `ConstraintListInvalid` is
|
|
128
|
+
* written among the literals at its rank's own place — LAST of the sixteen and BEFORE the escape — because
|
|
129
|
+
* `distribution.md §5.3` item 1 requires the store's members to be *"DISCOVERABLE in the type"*, and a
|
|
130
|
+
* member the declaration does not name is not discoverable from the type at all. **NO RANK OF `1`…`15`
|
|
131
|
+
* MOVES AND NO EXISTING TRIGGER MOVES: THE MEMBER IS APPENDED AS THE SIXTEENTH** (`contract.md §8.1`'s
|
|
132
|
+
* amended heading, whose algebra reads `11 + 2 + 1 + 1 + 1 = 16` ✓; the row that drives it is
|
|
133
|
+
* `docs/specs/storeroom-native/implementation-plan.md §10.9` row 8). **ITS TRIGGER IS THE VALIDATION OF
|
|
134
|
+
* THE SUPPLIED CONSTRAINT LIST** — at
|
|
135
|
+
* construction/startup, or of the LOADED state against that list at load — **and the store writes no byte of
|
|
136
|
+
* that list into the file and holds no register key for it** (`contract.md §7.1` step 4 and `§7.2` item 6 as
|
|
137
|
+
* amended 2026-10-15; `seams-and-lifecycle.md §8.1`).
|
|
86
138
|
*/
|
|
87
139
|
export type StoreStatus =
|
|
88
140
|
| 'AddressMalformed'
|
|
@@ -100,6 +152,7 @@ export type StoreStatus =
|
|
|
100
152
|
| 'FilePathUnreachable'
|
|
101
153
|
| 'ValueNotAdmitted'
|
|
102
154
|
| 'FileCommitFailed'
|
|
155
|
+
| 'ConstraintListInvalid'
|
|
103
156
|
| (string & {});
|
|
104
157
|
|
|
105
158
|
/**
|
|
@@ -189,9 +242,62 @@ export interface RollbackRecord {
|
|
|
189
242
|
}
|
|
190
243
|
|
|
191
244
|
/**
|
|
192
|
-
* **THE
|
|
193
|
-
* (`
|
|
194
|
-
*
|
|
245
|
+
* **THE ATTEMPT'S IDENTITY — THE KERNEL'S OWN ONE-MEMBER RECORD AND NOT THIS PACKAGE'S**
|
|
246
|
+
* (`attempt-lifecycle.md §2.4` item 1: *"`AttemptRef { id: string }` — the attempt's identity: a non-empty,
|
|
247
|
+
* kernel-unique token"*; read with `kernel-surface.md §1` item 4's closed record enumeration, which counts
|
|
248
|
+
* it as a named kernel-side shape).
|
|
249
|
+
*
|
|
250
|
+
* **IT IS DECLARED HERE FOR ONE POSITION AND NO OTHER**: the `attempt` member of the `CommitRecord` the
|
|
251
|
+
* instance's `settle` member takes (`§2.4` item 9 (f)'s *"each with its argument types"*). **No verb of
|
|
252
|
+
* this entry answers with it and this package mints it nowhere.**
|
|
253
|
+
*/
|
|
254
|
+
export interface AttemptRef {
|
|
255
|
+
/** The attempt's identity: a non-empty, kernel-unique token. */
|
|
256
|
+
readonly id: string;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* **THE ORDERING SEAM'S ONE ARGUMENT — THE KERNEL'S OWN `{ attempt, op, triggered, pending }` RECORD, AND
|
|
261
|
+
* NOT THE STORE'S `WriteRecord`** (`kernel-surface.md §2.1` item 2's return-shape block: *"`CommitRecord`,
|
|
262
|
+
* a record with exactly FOUR members, the FOURTH added at the `A108` landing pass of 2026-10-13"*; its
|
|
263
|
+
* `§1` item 4 counts it among the kernel's own named shapes).
|
|
264
|
+
*
|
|
265
|
+
* **THE RECORD THE KERNEL PASSES IS THIS ONE AND THE STORE'S IS NOT.** **The kernel passes the `CommitRecord`
|
|
266
|
+
* `commit` built and the pass's terminal arm reads again — one identity, at both instants** (`surface.md`
|
|
267
|
+
* `§2.4` item 9 (a)–(b)'s table: *"the record identity (the `CommitRecord` `commit` is building)"* then
|
|
268
|
+
* *"the SAME record identity"*; `PAR-JS-19`'s `supplier` cell: THE KERNEL, *"at instant (a) from `commit`
|
|
269
|
+
* … and at instant (b) from the pass's terminal arm"*). **AND IT IS `NOT` THE STORE'S OWN RECORD**:
|
|
270
|
+
* `kernel-surface.md §2.1` item 2's *"WHAT IT IS NOT"* clause reads *"the `CommitRecord` is the KERNEL'S
|
|
271
|
+
* OWN record and is NOT the store's `WriteResult`"* — the store's write answers `{op, watched, triggered}`
|
|
272
|
+
* and `WriteRecord` above is that three-member record, carrying NO `attempt` and NO `pending`.
|
|
273
|
+
*
|
|
274
|
+
* **SO THE `pending` MEMBER BELOW IS THE KERNEL'S, CARRIED VERBATIM FROM THE KERNEL'S OWN DECLARATION AND
|
|
275
|
+
* MINTED NOWHERE HERE** (`surface.md` `§2.4` item 9 (f)'s *"no `pending`-shaped record type this unit does
|
|
276
|
+
* not declare"*; `A116` (D4) — *"the carrier `CommitRecord.pending` and its two removal rules unchanged"*):
|
|
277
|
+
* it carries THE WHOLE RETURNED SET OF TRIGGERED CONSTRAINTS this call's write returned, each entry leaving
|
|
278
|
+
* it only by being checked off as it passes (`kernel-surface.md §2.1` item 2).
|
|
279
|
+
*
|
|
280
|
+
* **`triggered` and `pending` are the store's own returned handle set and the kernel's own member
|
|
281
|
+
* respectively, each read as a SET** (`§2.1` item 2; `Handle` above is this file's opaque-handle spelling);
|
|
282
|
+
* **`op` is the op the store's write returned, VERBATIM** (`JournalOp` above, the store's own eight-member
|
|
283
|
+
* record — `§2.1` item 2: *"the op the store's write returned, VERBATIM"*).
|
|
284
|
+
*/
|
|
285
|
+
export interface CommitRecord {
|
|
286
|
+
/** The attempt this commit opened — its identity (`attempt-lifecycle.md §2.4` item 1). */
|
|
287
|
+
readonly attempt: AttemptRef;
|
|
288
|
+
/** The op the store's write returned, VERBATIM (`JournalOp` above; `§2.1` item 2). */
|
|
289
|
+
readonly op: JournalOp;
|
|
290
|
+
/** The store's own `triggered` member, VERBATIM, read as a SET (`§2.1` item 2). */
|
|
291
|
+
readonly triggered: readonly Handle[];
|
|
292
|
+
/** THE WHOLE RETURNED SET OF TRIGGERED CONSTRAINTS, each entry leaving it only by being checked off as it passes (`§2.1` item 2). */
|
|
293
|
+
readonly pending: readonly Handle[];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* **THE INSTANCE `storeCreate` RETURNS — `{ register, on, off, settle }`, FOUR OWN MEMBERS AND NOTHING
|
|
298
|
+
* ELSE** (`distribution.md §5.2` item 2 read with `surface.md §2.1`'s dated clause (a) and `§2.4` item 9).
|
|
299
|
+
* **The instance's own state is released with the instance and by nothing else: none of the four is a
|
|
300
|
+
* release verb.**
|
|
195
301
|
*/
|
|
196
302
|
export interface StoreInstance {
|
|
197
303
|
/** Register `listener` under the opaque `handle`, and answer `undefined`. */
|
|
@@ -200,6 +306,41 @@ export interface StoreInstance {
|
|
|
200
306
|
on(address: Address, listener: Listener): Handle;
|
|
201
307
|
/** Withdraw the store-side home entry the `handle` names, and answer `undefined`. */
|
|
202
308
|
off(handle: Handle): void;
|
|
309
|
+
/**
|
|
310
|
+
* **THE ORDERING SEAM — `settle(record) -> undefined`** (`surface.md §2.4` item 9; `A116` (D1)–(D2);
|
|
311
|
+
* `PAR-JS-19`): the one member THE KERNEL CALLS and the entry implements, at the two instants of a
|
|
312
|
+
* kernel-driven write — **the adoption at the first call for a record identity**, taken before the write
|
|
313
|
+
* verb (the write in flight is withheld: the in-window invocation set is empty), **and the delivery at
|
|
314
|
+
* the second call for that identity**, taken at the pass's terminal arm (the residue standing in the
|
|
315
|
+
* record's own `pending` member is delivered through this instance's own registry, one invocation per
|
|
316
|
+
* handle, each with the triggering address as its single argument). **Every other form at the record
|
|
317
|
+
* position — absent, `undefined`, `null`, a primitive, a function, a `Proxy`, an identity this instance
|
|
318
|
+
* never adopted — throws the registration site's own `TypeError` and changes nothing.**
|
|
319
|
+
*
|
|
320
|
+
* **THE RECORD POSITION TAKES THE KERNEL'S OWN `CommitRecord` — `{ attempt, op, triggered, pending }`,
|
|
321
|
+
* FOUR MEMBERS — AND NOT THE STORE'S `WriteRecord`** (`surface.md` `§2.4` item 9 (f)'s *"each with its
|
|
322
|
+
* argument types"* read with item 9's own two-instant table; `PAR-JS-19`'s `supplier` cell; `A116` (D4):
|
|
323
|
+
* *"the carrier `CommitRecord.pending` and its two removal rules unchanged"*). **THE INSTANTS' OWN TABLE
|
|
324
|
+
* NAMES IT: the record is *"the `CommitRecord` `commit` is building"* at instant (a) and *"the SAME record
|
|
325
|
+
* identity"* at instant (b)** (`surface.md` `§2.4` item 9 (a)–(b)). **AND THE STORE'S RECORD IS NOT ONE:
|
|
326
|
+
* `WriteRecord` above is the three-member `{op, watched, triggered}` the `write` verb answers with and
|
|
327
|
+
* carries NO `pending` member, `PAR-JS-13` is that record's returned `op` field (`parameter-semantics.md
|
|
328
|
+
* §2.13`) and not the record's own shape, and the kernel's record carries TWO of the store's members
|
|
329
|
+
* VERBATIM beside its own `attempt` identity and its own `pending` member** (`kernel-surface.md §2.1` item
|
|
330
|
+
* 2's *"WHAT IT IS NOT"* clause: *"the `CommitRecord` is the KERNEL'S OWN record and is NOT the store's
|
|
331
|
+
* `WriteResult`"*).
|
|
332
|
+
*
|
|
333
|
+
* **`CommitRecord` IS THE KERNEL'S DECLARED SHAPE AND IS NOT MINTED HERE** (`surface.md` `§2.4` item 9
|
|
334
|
+
* (f) forbids *"a `pending`-shaped record type this unit does not declare"*, and this unit declares none):
|
|
335
|
+
* the type is declared above with the kernel's own four members and cited from its own unit's declaration
|
|
336
|
+
* — `kernel-surface.md §1` item 4's closed record enumeration, `§2.1` item 2 for the record, and
|
|
337
|
+
* `attempt-lifecycle.md §2.4` item 1 for its `AttemptRef` — **and NO named export is added for it or for
|
|
338
|
+
* `settle`.**
|
|
339
|
+
*
|
|
340
|
+
* **It is NOT a named export of this entry** (`package.md §1.3` item 3): it is reached through
|
|
341
|
+
* `storeCreate`'s own product alone.
|
|
342
|
+
*/
|
|
343
|
+
settle(record: CommitRecord): void;
|
|
203
344
|
}
|
|
204
345
|
|
|
205
346
|
/**
|
|
@@ -225,8 +366,27 @@ export function read(instance: StoreInstance, address: Address, tier?: TierSet):
|
|
|
225
366
|
/** The same read, narrowed to a leaf — a branch answers `ReadTargetIsBranch`; `tier` is `TierSet`. */
|
|
226
367
|
export function readLiteral(instance: StoreInstance, address: Address, tier?: TierSet): unknown;
|
|
227
368
|
|
|
228
|
-
/**
|
|
229
|
-
|
|
369
|
+
/**
|
|
370
|
+
* Write `value` at `address` on `tier` — EXACTLY ONE token, never an array (`PAR-JS-7`).
|
|
371
|
+
*
|
|
372
|
+
* **⟶ AMENDED 2026-10-15 (`surface.md §2.2`'s dated clause of 2026-10-15; `parameter-semantics.md §2.20`):
|
|
373
|
+
* THE DECLARED ORDER IS `write(instance, address, tier, value, commit?)`** — **FOUR REQUIRED ARGUMENTS
|
|
374
|
+
* AND THE OPTIONAL ONE AT POSITION FIVE** (`proposal-review.md §22.5` item 5) — and this is the published
|
|
375
|
+
* declaration file `surface.md §2.4` item 9 (f) names.
|
|
376
|
+
*
|
|
377
|
+
* **AN ABSENT `commit` IS IN DOMAIN** (§2.2 clause 3: *"the write opens or joins a commit all the same"*)
|
|
378
|
+
* and **NO DEFAULT RECORD IS FABRICATED FOR IT**; **the admitted form is the kernel's own `CommitRecord`**
|
|
379
|
+
* (`surface.md §2.4` item 9 (g) item 1: an object carrying a `pending` member present and not `undefined`),
|
|
380
|
+
* and **every other form at this position throws the registration site's own `TypeError`**, whose `status`
|
|
381
|
+
* member is ABSENT. **A REFUSED POSITION STOPS THE WRITE**: no verb is reached and no byte moves.
|
|
382
|
+
*/
|
|
383
|
+
export function write(
|
|
384
|
+
instance: StoreInstance,
|
|
385
|
+
address: Address,
|
|
386
|
+
tier: Tier,
|
|
387
|
+
value: unknown,
|
|
388
|
+
commit?: CommitRecord,
|
|
389
|
+
): WriteRecord;
|
|
230
390
|
|
|
231
391
|
/**
|
|
232
392
|
* Remove the versions the address names, and answer the operation's record.
|
package/index.mjs
CHANGED
|
@@ -12,15 +12,24 @@
|
|
|
12
12
|
// CONSTRUCTS THE CROSSING MODEL, HANDS IT TO THE ADDON'S `storeCreate`/`call` DISPATCH, AND MAPS THE
|
|
13
13
|
// ADDON'S ANSWER BACK INTO JS VALUES.** **THE STORE'S OWN LOGIC IS THE RUST CORE'S**
|
|
14
14
|
// (`bindings/js/src/crossing.rs`): the register tree, the anchors, the journal and its compaction, the
|
|
15
|
-
// listener home and the prefix test, the file image and its boot, the
|
|
15
|
+
// listener home and the prefix test, the file image and its boot, the SIXTEEN-member fail set and its
|
|
16
16
|
// generated messages are ALL reached through the facade, and NOTHING of them is re-implemented here.
|
|
17
17
|
//
|
|
18
|
+
// **⟶ RE-SPELLED 2026-10-15 BY THE GATE-4 FINDINGS PASS: THE FAIL SET'S FIGURE ON THE LINE ABOVE — the
|
|
19
|
+
// as-filed *"the fifteen-member fail set"* — IS THE FILING-TIME PRINT AND IS READ THROUGH THIS CLAUSE.
|
|
20
|
+
// THE OPERATIVE READING IS *"the SIXTEEN-member fail set"*, with `ConstraintListInvalid` at rank `16` and
|
|
21
|
+
// `FileCommitFailed` at `15`, so `FileCommitFailed` is NOT the last member from that date
|
|
22
|
+
// (`11 + 2 + 1 + 1 + 1 = 16` ✓).** The set is the store's own and is carried, never minted, here
|
|
23
|
+
// (`docs/specs/storeroom-native/contract.md §8.1`'s dated clause of 2026-10-15, the ONE home of the set's
|
|
24
|
+
// size; `§8.2` for the appended member's generated row; `src/error.rs`'s `CODES`, `[&'static str; 16]`,
|
|
25
|
+
// with `ConstraintListInvalid` last; `bindings/js/index.d.ts`'s `StoreStatus`, the published spelling).
|
|
26
|
+
//
|
|
18
27
|
// **WHAT STAYS IN JS, AND WHY IT IS NOT STORE LOGIC** (`A75`: *"THE REGISTRY, THE OPAQUE HANDLE AND THE
|
|
19
28
|
// SINGLE FAILURE FORM STAY IN JS (they are the PACKAGE's surface, `§2.4`)"*):
|
|
20
29
|
// * **THE PACKAGE'S OWN OPAQUE HANDLE** (`surface.md §2.3` item 2, `DD-14`): a frozen, memberless JS
|
|
21
30
|
// object whose token is private — the store's token crosses OUT of the addon and is wrapped here.
|
|
22
31
|
// * **THE PACKAGE'S OWN REGISTRY** (`surface.md §2.4`): the caller's FUNCTION, held per instance and
|
|
23
|
-
// reached through the
|
|
32
|
+
// reached through the member `storeCreate` returns (`register(handle, listener)`) — **⟶ RE-SPELLED 2026-10-16: the `ONE member` figure this line printed is the AS-FILED `surface.md §2.4` item 5 (a) reading, and the instance's OPERATIVE member set is `{ register, on, off, settle }`, FOUR OWN MEMBERS (`surface.md §2.7` item 8 AS AMENDED; `§2.11` clause 7; `docs/decisions.md` `A116` (D1)) — the registry being reached through each of them**. **The store
|
|
24
33
|
// returns handles and invokes nothing** (`A57`), so the invocation is the package's — performed after
|
|
25
34
|
// the addon's call has returned, with the triggering ADDRESS as its ONE argument (`PAR-JS-12`).
|
|
26
35
|
// * **THE SINGLE FAILURE FORM** (`surface.md §2.5`, `DD-12`): the addon THROWS the store's own
|
|
@@ -75,6 +84,59 @@ import { types } from 'node:util';
|
|
|
75
84
|
const require_ = createRequire(import.meta.url);
|
|
76
85
|
const ADDON_PATH = join(dirOf(fileURLToPath(import.meta.url)), 'build', 'Release', 'storeroom_js_binding.node');
|
|
77
86
|
|
|
87
|
+
/**
|
|
88
|
+
* **THE PASS'S OWN CHECK-OFFS, CARRIED FROM THE KERNEL TO THE TERMINAL ARM'S DELIVERY UNDER A SYMBOL KEY
|
|
89
|
+
* (`docs/decisions.md` · `A117` (D5)–(D6); `surface.md §2.7` item 7's keying of 2026-10-15).**
|
|
90
|
+
*
|
|
91
|
+
* `§2.7` item 7 (a) delivers **THE RESIDUE** — *"the handle set that stands in `CommitRecord.pending` at
|
|
92
|
+
* that instant"* — and item 7's keying of 2026-10-15 fixes what the check-off consumed: *"the check-off
|
|
93
|
+
* consumes the evaluated pair's own delivery of that identity and NEVER that identity's whole owed
|
|
94
|
+
* delivery"*. **So the residue is one term of the arm's delivered set and the pass's own checked-off
|
|
95
|
+
* identities are a second**, and this key is how the kernel's finding reaches this file: the kernel
|
|
96
|
+
* records each identity its check-off took and publishes the list on the record AT ITS PASSING ARM, before
|
|
97
|
+
* it hands that record back to this instance's own `settle` member.
|
|
98
|
+
*
|
|
99
|
+
* **THE KEY IS A SYMBOL ON PURPOSE** (`A117` (D6)): **NO MEMBER IS ADDED** — `CommitRecord` keeps its four
|
|
100
|
+
* members and the record's enumerable shape does not move, so no census of a record's members changes and
|
|
101
|
+
* nothing of the named-shape set is widened. **AND THE ENTRY DOES NOT IMPORT THE KERNEL TO READ IT** — the
|
|
102
|
+
* same well-known symbol is declared on both sides, which is what keeps the entry's zero-dependency rule
|
|
103
|
+
* and `kernel-surface.md §1` item 1's one checkout home intact. **A RECORD CARRYING NO SUCH KEY** — a
|
|
104
|
+
* record this instance adopted from a caller, one from a session without the kernel, and the failing
|
|
105
|
+
* arm's own record — reaches the arm's residue term ALONE and behaves exactly as it behaved before.
|
|
106
|
+
*/
|
|
107
|
+
const CHECKED_OFF = Symbol.for('provident-storeroom.checked-off-at-the-terminal-arm');
|
|
108
|
+
|
|
109
|
+
/// **⟶ ADDED 2026-10-15 (`surface.md §2.11` clauses 1–2; `contract.md §7.2` item 2 as amended) — THE PASSING
|
|
110
|
+
/// ARM'S OWN MARK: THE SAME DEVICE AS `CHECKED_OFF` ABOVE, ONE CLAUSE EARLIER.**
|
|
111
|
+
///
|
|
112
|
+
/// **THE TERMINAL ARM'S OWN ACT IS SCOPED TO THE PASSING ARM ALONE** (clause 1: *"the `file` tier, the
|
|
113
|
+
/// TERMINAL ARM and the PASSING ARM alone"*), **and the seam reaches ONE instant on BOTH arms**: a
|
|
114
|
+
/// `file`-tier write whose pass FAILED arrives at this same delivery with its record in hand, and clause 1
|
|
115
|
+
/// refuses it a save and a store call of its own — *"a failing arm drives no save"*. **THE ARM IS THE
|
|
116
|
+
/// KERNEL'S OWN FACT** (`attempt-lifecycle.md §2.4` item 4), so the KERNEL marks the record it settled on
|
|
117
|
+
/// its passing arm and the entry reads THAT MARK and nothing else — never a residue, never a member a
|
|
118
|
+
/// caller may set, and never a second store call on the failing arm.
|
|
119
|
+
///
|
|
120
|
+
/// **THE KEY IS A SYMBOL ON PURPOSE, EXACTLY AS `CHECKED_OFF`'s IS** (`A117` (D6)): **NO MEMBER IS ADDED** —
|
|
121
|
+
/// `CommitRecord` keeps its four members, `record.pending` stands exactly as the pass left it, and no
|
|
122
|
+
/// census moves. **THE ENTRY DOES NOT IMPORT THE KERNEL TO READ IT**: the same well-known symbol is
|
|
123
|
+
/// declared on both sides. **A RECORD CARRYING NO SUCH KEY** — a caller's own record, and the failing arm's
|
|
124
|
+
/// own record — performs no save and behaves exactly as it behaved before.
|
|
125
|
+
const SETTLED_ON_THE_PASSING_ARM = Symbol.for('provident-storeroom.settled-on-the-passing-arm');
|
|
126
|
+
|
|
127
|
+
/// **⟶ ADDED 2026-10-15 — THE FAILED SAVE'S OWN MARK, THE SIBLING OF THE KEY ABOVE AND READ BY THE KERNEL'S
|
|
128
|
+
/// OWN CATCH** (`docs/specs/storeroom-js/surface.md §2.11` clause 5; `kernel-surface.md §2.1` items 3–5).
|
|
129
|
+
/// **`§2.11` clause 5's save IS A CONSTRAINT, EVALUATED LAST — SO A SAVE THAT FAILS IS REPORTED BY THE PASS
|
|
130
|
+
/// THAT FAILED AND NOT BY THE PASSING ARM**: the failed save's own log gains the `outcome` entry, the
|
|
131
|
+
/// terminal answer returns that closed record's FINAL log, and the report carries the rollback that
|
|
132
|
+
/// actually happened (`§2.6` item 3). **THE ENTRY MINTS NO TOKEN AND CONVERTS NO FORM**: it tells the
|
|
133
|
+
/// kernel WHICH ARM this is, on the record identity it was handed, by carrying THE VERY THROWABLE it
|
|
134
|
+
/// rethrows — while the store's own two-member form crosses UNCHANGED. **IT IS A SYMBOL KEY ON PURPOSE**
|
|
135
|
+
/// (`A117` (D6)): `CommitRecord` keeps its four members, `record.pending` stands exactly as the pass left
|
|
136
|
+
/// it, and no census moves. **A RECORD CARRYING NO SUCH KEY** — every arm but the failed save — is
|
|
137
|
+
/// untouched by it.
|
|
138
|
+
const SAVE_FAILED_AT_THE_TERMINAL_ARM = Symbol.for('provident-storeroom.save-failed-at-the-terminal-arm');
|
|
139
|
+
|
|
78
140
|
// ---------------------------------------------------------------------------------------------
|
|
79
141
|
// THE RESOLUTION RULE — THREE RUNGS, IN ORDER, AND THE CLOSED KEY SET (`docs/specs/storeroom-publish/
|
|
80
142
|
// resolution.md §2` · `§3`; `docs/specs/storeroom-publish/contract.md §1.1` · `§1.3` · `§1.5`).
|
|
@@ -1089,8 +1151,92 @@ function encodeListeners(listeners) {
|
|
|
1089
1151
|
});
|
|
1090
1152
|
}
|
|
1091
1153
|
|
|
1092
|
-
/// `surface.md §2.1`
|
|
1093
|
-
///
|
|
1154
|
+
/// **⟶ ADDED 2026-10-15 (`parameter-semantics.md §2.21`; `surface.md §2.1`'s `cfg` block dated 2026-10-15;
|
|
1155
|
+
/// `contract.md §8.1` #16) — THE CONSTRUCTION'S FOURTH DECLARED KEY, `constraints`: THE LIST'S OWN WALK.**
|
|
1156
|
+
///
|
|
1157
|
+
/// **THE CLASS DECISION IS TAKEN FIRST, ON THE VALUE AS IT IS, AND NO COERCION IS PERFORMED ANYWHERE
|
|
1158
|
+
/// HERE** (`A76`'s part (1)): a `Proxy`, a class extending `Array` and every non-array is the LIST's own
|
|
1159
|
+
/// outside form and is carried as one; a plain array is walked element by element; **and ONE ELEMENT
|
|
1160
|
+
/// OUTSIDE THE `{ address, id }` PAIR'S SHAPE crosses as THE FAILING ENTRY'S OWN `<SEGMENT>` SPELLING**
|
|
1161
|
+
/// (`§8.2`'s row: *"the failing ENTRY's `address` spelling, joined by `/` … or the element's own position
|
|
1162
|
+
/// printed bare where the failing element carries no address at all"*). **THE CODE AND THE MESSAGE STAY THE
|
|
1163
|
+
/// STORE'S** (`§8.1` #16, `DD-40`): nothing here mints a status and nothing here authors a sentence.
|
|
1164
|
+
function encodeConstraints(constraints) {
|
|
1165
|
+
if (constraints === undefined) return undefined;
|
|
1166
|
+
if (constraints === null) return null;
|
|
1167
|
+
if (types.isProxy(constraints)) return { bad: 'non-array' }; // `DD-34`'s class order, taken first
|
|
1168
|
+
if (!Array.isArray(constraints)) return { bad: 'non-array' };
|
|
1169
|
+
if (arrayClass(constraints) === 'class') return { bad: 'non-array' };
|
|
1170
|
+
return constraints.map((entry, position) => constraintEntry(entry, position));
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
/// ONE `constraints[]` ELEMENT: the closed `{ address, id }` pair, or the element's own `<SEGMENT>`
|
|
1174
|
+
/// spelling (`§8.2`). **AN ELEMENT THAT IS NOT A PLAIN OBJECT — an array, a `Proxy`, a class instance and
|
|
1175
|
+
/// every non-object included — CARRIES NO ADDRESS AT ALL**, so its slot is the element's own POSITION
|
|
1176
|
+
/// printed bare.
|
|
1177
|
+
function constraintEntry(entry, position) {
|
|
1178
|
+
const where = `the constraint entry at position ${position}`;
|
|
1179
|
+
if (!isPlainObjectValue(entry)) return { bad: 'element', subject: where };
|
|
1180
|
+
if (!Object.hasOwn(entry, 'address') || entry.address === undefined) {
|
|
1181
|
+
return { bad: 'element', subject: where };
|
|
1182
|
+
}
|
|
1183
|
+
const address = constraintAddress(entry.address);
|
|
1184
|
+
if (typeof address === 'string') return { bad: 'element', subject: address };
|
|
1185
|
+
// AN ELEMENT CARRYING NO `id` AT ALL IS THE SAME OUTSIDE FORM AS ONE WHOSE `id` IS NOT A STRING: the
|
|
1186
|
+
// `<SEGMENT>` slot prints the entry's own `address` spelling and the `<KEYLIST>`'s members are the
|
|
1187
|
+
// entry's own, read by the store's generator and never here.
|
|
1188
|
+
if (
|
|
1189
|
+
!Object.hasOwn(entry, 'id')
|
|
1190
|
+
|| entry.id === undefined
|
|
1191
|
+
|| typeof entry.id !== 'string'
|
|
1192
|
+
|| entry.id === ''
|
|
1193
|
+
) {
|
|
1194
|
+
return { bad: 'element', subject: spellConstraintAddress(address.s) };
|
|
1195
|
+
}
|
|
1196
|
+
return { address, id: entry.id };
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
/// `§1.5`'s segment array as the carrier `encodeAddress` declares it — **or, where the value lies outside
|
|
1200
|
+
/// that domain, the failing ELEMENT's own `address` spelling as a STRING** (`§8.2`'s `<SEGMENT>` slot: a
|
|
1201
|
+
/// string key single-quoted, an integer index bare, joined by `/`).
|
|
1202
|
+
function constraintAddress(address) {
|
|
1203
|
+
if (types.isProxy(address) || !Array.isArray(address) || arrayClass(address) === 'class') {
|
|
1204
|
+
return `'${valueTargetSpelling(address)}'`;
|
|
1205
|
+
}
|
|
1206
|
+
const segments = [];
|
|
1207
|
+
for (let i = 0; i < address.length; i += 1) {
|
|
1208
|
+
if (!(i in address)) {
|
|
1209
|
+
return `${spellConstraintAddress(segments)} and no segment at position ${i}`;
|
|
1210
|
+
}
|
|
1211
|
+
const segment = address[i];
|
|
1212
|
+
if (typeof segment === 'string' && !hasLoneSurrogate(segment)) {
|
|
1213
|
+
segments.push(segment);
|
|
1214
|
+
} else if (typeof segment === 'number' && Number.isInteger(segment) && segment >= 0
|
|
1215
|
+
&& Number.isSafeInteger(segment)) {
|
|
1216
|
+
segments.push(segment);
|
|
1217
|
+
} else {
|
|
1218
|
+
return `${spellConstraintAddress(segments)} and ${classSpelling(segment)} at position ${i}`;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return { k: 'L', s: segments };
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
/// `§8.2`'s whole-address spelling: **a string key SINGLE-QUOTED (`'a'`) and an integer index BARE (`0`),
|
|
1225
|
+
/// JOINED BY `/`** — the same spelling the store's own generator prints at its `<SEGMENT>` slot.
|
|
1226
|
+
function spellConstraintAddress(segments) {
|
|
1227
|
+
return segments
|
|
1228
|
+
.map((segment) => (typeof segment === 'string' ? `'${segment}'` : String(segment)))
|
|
1229
|
+
.join('/');
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/// `surface.md §2.1` / `DD-36`: the as-filed *"`cfg` carries the store's THREE declared keys and no
|
|
1233
|
+
/// fourth"* is read THROUGH this clause and is **the FOUR declared keys and no FIFTH** — `filePath` ·
|
|
1234
|
+
/// `journalLength` · `listeners` · `constraints` (`surface.md §2.1`'s `cfg` block dated 2026-10-15 and its
|
|
1235
|
+
/// dated clause of 2026-10-16; `parameter-semantics.md §2.21` = `PAR-JS-21`) — **and a CALLER-SUPPLIED key
|
|
1236
|
+
/// beyond those four is IGNORED, never refused: no code, no refusal and no member moved** (`§2.1`'s dated
|
|
1237
|
+
/// clause of 2026-10-16, `contract.md §7.1`'s third-key row governing the caller's key; `§8.1`'s
|
|
1238
|
+
/// complement). **Each key's own ABSENCE is the member's own absence** — `crossing.md §1.3`'s
|
|
1239
|
+
/// absent-versus-`undefined` rule reads a
|
|
1094
1240
|
/// `cfg` key by MEMBERSHIP and never by arity, and **`A76`/`JS-5` fixes that membership as OWNERSHIP:
|
|
1095
1241
|
/// `Object.hasOwn` and never `in`, which walks the prototype chain.**
|
|
1096
1242
|
///
|
|
@@ -1107,15 +1253,21 @@ function encodeListeners(listeners) {
|
|
|
1107
1253
|
function encodeConfig(cfg) {
|
|
1108
1254
|
if (!isPlainObjectValue(cfg)) {
|
|
1109
1255
|
boundaryReject(
|
|
1110
|
-
'AddressMalformed', // `PAR-JS-1`'s declared answer for every outside form of `cfg`, carried
|
|
1256
|
+
'AddressMalformed', // `PAR-JS-1`'s declared answer for every outside form of `cfg`, carried — **AND THE MESSAGE BELOW IS RE-SPELLED IN PLACE, 2026-10-16: *"carrying the store's three declared keys"* READS *"carrying the store's four declared keys"*, THE COUNT ALONE MOVING, because the set is `filePath` · `journalLength` · `listeners` · `constraints` (`§2.1`'s `cfg` block and dated clause, both of 2026-10-15), because the sentence's subject is the `cfg` CARRIER CLASS and NEVER a caller obligation (a CALLER-SUPPLIED key BEYOND the four is still IGNORED and never refused, `contract.md §7.1` — no semantics and no refusal path moves with the word), and because NOTHING PINNED THE OLD WORDING: no clause of `docs/specs/**` declares this message's figure and no test reads it — the drives read the TARGET `cfg` and the CLASS that failed (`negative-generators.test.mjs` · `registry.test.mjs`) — so it was ordinary prose written when the count was three and NOT a clause's own byte.**
|
|
1111
1257
|
'cfg',
|
|
1112
|
-
`the construction's cfg is ${classSpelling(cfg)}, and cfg is one plain object carrying the store's
|
|
1258
|
+
`the construction's cfg is ${classSpelling(cfg)}, and cfg is one plain object carrying the store's four declared keys`,
|
|
1113
1259
|
);
|
|
1114
1260
|
}
|
|
1115
1261
|
const out = {};
|
|
1116
1262
|
if (Object.hasOwn(cfg, 'filePath')) out.filePath = encodeFilePath(cfg.filePath);
|
|
1117
1263
|
if (Object.hasOwn(cfg, 'journalLength')) out.journalLength = encodeJournalLength(cfg.journalLength);
|
|
1118
1264
|
if (Object.hasOwn(cfg, 'listeners')) out.listeners = encodeListeners(cfg.listeners);
|
|
1265
|
+
// **⟶ THE FOURTH DECLARED KEY** (`§2.21`; `§2.1`'s `cfg` block dated 2026-10-15): `constraints` passes
|
|
1266
|
+
// through by the SAME membership rule the three above take, so a key the caller did not supply is
|
|
1267
|
+
// ABSENT and a key the caller supplied as `undefined` is the key's own outside form. **A key BEYOND the
|
|
1268
|
+
// four is IGNORED and produces no code** (`§8.1`'s complement), and no default, no rename and no fifth
|
|
1269
|
+
// key is added here (`DD-36`).
|
|
1270
|
+
if (Object.hasOwn(cfg, 'constraints')) out.constraints = encodeConstraints(cfg.constraints);
|
|
1119
1271
|
return out;
|
|
1120
1272
|
}
|
|
1121
1273
|
|
|
@@ -1190,7 +1342,7 @@ function decodeJournalOp(encoded) {
|
|
|
1190
1342
|
// THE PACKAGE'S OWN SURFACE — the opaque handle (`§2.3` item 2) and the per-instance registry (`§2.4`)
|
|
1191
1343
|
// ---------------------------------------------------------------------------------------------
|
|
1192
1344
|
/// **THE PACKAGE'S OWN INSTANCE HANDLE'S STATE**, keyed by the instance the factory returned. The handle
|
|
1193
|
-
/// itself carries EXACTLY ONE member, `register` (`surface.md §2.4` item 5 (a)).
|
|
1345
|
+
/// itself carries EXACTLY ONE member, `register` (`surface.md §2.4` item 5 (a)) — **⟶ RE-SPELLED 2026-10-16: THAT ONE-MEMBER FIGURE IS THE AS-FILED READING AND IS SUPERSEDED AS A MEMBER-SET FIGURE — the instance's OPERATIVE member set is `{ register, on, off, settle }`, FOUR OWN MEMBERS AND NOTHING ELSE (`surface.md §2.7` item 8 AS AMENDED, where the as-filed `{register, on, off}` reads `{register, on, off, settle}`; `§2.11` clause 7; `docs/decisions.md` `A116` (D1)) — while the WeakMap below is still keyed by the INSTANCE alone and no member is added to it by this clause.**
|
|
1194
1346
|
const INSTANCES = new WeakMap(); // instance -> {id, tokens: Map(handle -> token)}
|
|
1195
1347
|
|
|
1196
1348
|
function wrapHandles(state, tokens) {
|
|
@@ -1287,14 +1439,17 @@ function writeCall(state, args, fault) {
|
|
|
1287
1439
|
// (`A63`), no `exists` verb exists (`§2.9` item 3) and no release verb is declared (`A74`).
|
|
1288
1440
|
// ---------------------------------------------------------------------------------------------
|
|
1289
1441
|
|
|
1290
|
-
/// `§2.1`: `storeCreate(cfg)` takes ONE plain object carrying the store's
|
|
1291
|
-
/// through WITHOUT adding a default, a rename or a
|
|
1292
|
-
///
|
|
1442
|
+
/// `§2.1`: `storeCreate(cfg)` takes ONE plain object carrying the store's FOUR declared keys, passes them
|
|
1443
|
+
/// through WITHOUT adding a default, a rename or a fifth key (`DD-36`) — **the as-filed *"THREE declared
|
|
1444
|
+
/// keys … a fourth key"* is read THROUGH this re-spelling, at `§2.1`'s `cfg` block dated 2026-10-15 and its
|
|
1445
|
+
/// dated clause of 2026-10-16, and a CALLER-SUPPLIED key beyond the four is IGNORED, never refused
|
|
1446
|
+
/// (`contract.md §7.1`; `§8.1`'s complement)** — and **never returns a partial instance** — it throws the
|
|
1447
|
+
/// single failure form instead. **⟶ `§2.1`'s dated clause (a), LANDED 2026-10-11
|
|
1293
1448
|
/// BY THE `Q1` CONTRACT AMENDMENT, RE-DERIVES THE MEMBER FIGURE THIS SENTENCE CARRIED: *"the object it
|
|
1294
1449
|
/// returns carries EXACTLY the one own member `surface.md §2.4` item 5 (a) declares, and not one member
|
|
1295
1450
|
/// beside it"* STANDS BYTE-FOR-BYTE ABOVE AND IS READ THROUGH THIS CLAUSE — from this date the member set
|
|
1296
|
-
/// is `{ register, on, off }`, THREE OWN MEMBERS AND NOTHING ELSE, and `§2.4` item 5 (a)'s *"one own
|
|
1297
|
-
/// member"* is superseded AS A MEMBER-SET FIGURE at its own `§` by the same amendment.** **THE MODULE
|
|
1451
|
+
/// is `{ register, on, off }`, THREE OWN MEMBERS AND NOTHING ELSE — **⟶ AND THAT FIGURE IS RE-SPELLED IN PLACE, 2026-10-16 BY THE FILE-TIER-SAVE COMMENT PASS: *"THREE OWN MEMBERS"* IS THE 2026-10-11 FIGURE OF THE CLAUSE ABOVE AND NOT THE OPERATIVE ONE, WHICH IS `{ register, on, off, settle }`, FOUR OWN MEMBERS AND NOTHING ELSE** — the fourth being the `A116` ORDERING SEAM, the ONE member the KERNEL calls and the entry implements (`docs/decisions.md` `A116` (D1): the set *"opens by ONE clause"* to carry it; (D3): the lift is NARROW, so NO FIFTH member; its own home is `surface.md §2.4` item 9, and a CALLER's addressable sub-surface stays the three there declared), the count read at `surface.md §2.7` item 8 AS AMENDED (the as-filed `{register, on, off}` there is *"SUPERSEDED AS FIGURES"* and reads `{register, on, off, settle}`), at `§2.11` clause 7, and by the live battery's `FTS-12.1`, whose members are exactly those four. And `§2.4` item 5 (a)'s *"one own
|
|
1452
|
+
/// member"* is superseded AS A MEMBER-SET FIGURE at its own `§` by the same amendment (`surface.md §2.11` clause 7: *"the instance's member set stays `{ register, on, off, settle }`"*).** **THE MODULE
|
|
1298
1453
|
/// NAMESPACE IS UNMOVED at the eight declared verbs: neither new member is a named export, because both
|
|
1299
1454
|
/// are reached through THIS factory's own product and through nothing else** (`surface.md §2.1`'s dated
|
|
1300
1455
|
/// clauses (a)–(b); `A79`).
|
|
@@ -1314,7 +1469,17 @@ export function storeCreate(cfg) {
|
|
|
1314
1469
|
// (rule 2, never a fan-out). **⟶ AND `off` — the ONE declared member that DOES remove an entry —
|
|
1315
1470
|
// removes THE ONE THE HANDLE NAMES** (`§2.4` item 7 (b); `DD-53`), while the instance's own state is
|
|
1316
1471
|
// still released with the instance and by nothing else (`DD-17`; `A74`: `off` is not a release verb).
|
|
1317
|
-
|
|
1472
|
+
// **`withheld` IS THE WRITE-IN-FLIGHT SET** (`§2.4` item 9's instant (a)): the record identities this
|
|
1473
|
+
// instance has adopted as kernel-driven writes, whose post-verb invocation this instance withholds.
|
|
1474
|
+
// It holds IDENTITIES and no function, no handle and no address.
|
|
1475
|
+
const state = { id, tokens: new Map(), registry: new Map(), withheld: new Set(), adopted: new Set(), answered: new Map(), delivered: new WeakSet() };
|
|
1476
|
+
// **TWO STRUCTURES CARRY THE ADOPTION** (`§2.4` item 9 (a)–(b)): `adopted` holds the record identities
|
|
1477
|
+
// whose own write verb has NOT YET ANSWERED — the identity a write in flight is keyed by, and the one
|
|
1478
|
+
// identity per write the entry's own verb consumes — and `answered` is THE LEDGER, mapping each adopted
|
|
1479
|
+
// identity to THE IDENTITY THE WRITE ITSELF RETURNED, which is the identity the terminal arm reads the
|
|
1480
|
+
// residue off (`record.pending`, the member `K-2` fills from its own verb's returned set and the member
|
|
1481
|
+
// the pass checks entries off in as they pass). **BOTH ARE EMPTIED BY THE TERMINAL ARM**: a pass that
|
|
1482
|
+
// reaches its terminal instant is the only writer either structure has.
|
|
1318
1483
|
const instance = {
|
|
1319
1484
|
/// `surface.md §2.4` item 7 (a) / `§2.1`'s dated clause (a): **`on(address, listener) -> handle`** — the
|
|
1320
1485
|
/// combined call `A79` adopts, whose clauses are `§2.4` item 7 (a) and whose order is FIXED there.
|
|
@@ -1335,6 +1500,13 @@ export function storeCreate(cfg) {
|
|
|
1335
1500
|
register(handle, listener) {
|
|
1336
1501
|
return registerOn(state, handle, listener);
|
|
1337
1502
|
},
|
|
1503
|
+
/// `surface.md §2.4` item 9 / `§2.1`'s dated clause (a): **`settle(record) -> undefined`** — THE
|
|
1504
|
+
/// ORDERING SEAM, the one member the kernel calls and the entry implements, at the two instants of a
|
|
1505
|
+
/// kernel-driven write (`A116` (D1)–(D2)). **It is NOT a ninth named export of the entry**
|
|
1506
|
+
/// (`package.md §1.3` item 3): it is reached through the factory's own product alone.
|
|
1507
|
+
settle(record) {
|
|
1508
|
+
return settleOn(state, record, arguments.length >= 1);
|
|
1509
|
+
},
|
|
1338
1510
|
};
|
|
1339
1511
|
INSTANCES.set(instance, state);
|
|
1340
1512
|
return instance;
|
|
@@ -1360,15 +1532,79 @@ export function readLiteral(instance, address, tier) {
|
|
|
1360
1532
|
}
|
|
1361
1533
|
|
|
1362
1534
|
/// `PAR-JS-13`: the returned record is `{op, watched, triggered}` — fresh on every call, never a view.
|
|
1363
|
-
|
|
1535
|
+
///
|
|
1536
|
+
/// **⟶ AMENDED 2026-10-15 (`surface.md §2.2`'s dated clause of 2026-10-15; `parameter-semantics.md §2.20`):
|
|
1537
|
+
/// THE DECLARED ORDER IS `write(instance, address, tier, value, commit?)`** — FOUR REQUIRED ARGUMENTS AND
|
|
1538
|
+
/// THE OPTIONAL ONE AT POSITION FIVE (`proposal-review.md §22.5` item 5). **THE PACKAGE ADDS NO ARITY
|
|
1539
|
+
/// CHECK, NO DEFAULT AND NO VALIDATION OF ITS OWN AT THIS POSITION** (§2.2 clause 3): an ABSENT `commit` is
|
|
1540
|
+
/// IN DOMAIN — *"the write opens or joins a commit all the same"* — and **no default record is fabricated
|
|
1541
|
+
/// for it.**
|
|
1542
|
+
///
|
|
1543
|
+
/// **THE FIFTH POSITION'S CLASS TEST IS `§2.4` ITEM 9 (g) ITEM 1's OWN** — *"an object position is a record
|
|
1544
|
+
/// position only where it CARRIES A `pending` MEMBER whose value is present and not `undefined`"* — **and
|
|
1545
|
+
/// ITS ANSWER IS ONE INSTANCE OF ONE CLASS, `TypeError`, whose `status` MEMBER IS ABSENT and whose string
|
|
1546
|
+
/// `message` member is required** (`§2.20`'s answer cell; the same refusal `settleOn` takes at the record
|
|
1547
|
+
/// position). **A REFUSED POSITION STOPS THE WRITE**: no store call is reached, so no version lands and no
|
|
1548
|
+
/// byte moves. **IT IS A CLASS TEST AND NEVER AN IDENTITY TEST** — no clause reads the caller's history
|
|
1549
|
+
/// here.
|
|
1550
|
+
function commitPositionRefusal(commit) {
|
|
1551
|
+
if (commit !== null && typeof commit === 'object') {
|
|
1552
|
+
// **A `Proxy` IS OUTSIDE THE POSITION'S DOMAIN** (`§2.20`'s outside-value row) and is refused BEFORE a
|
|
1553
|
+
// member is read from it, so a `get` trap is never raised — the class order `encodeAddress` and
|
|
1554
|
+
// `encodeTier` already take at their own carriers (`A76`/`JS-2`).
|
|
1555
|
+
if (!types.isProxy(commit) && !Array.isArray(commit)) {
|
|
1556
|
+
let pending;
|
|
1557
|
+
try {
|
|
1558
|
+
pending = commit.pending;
|
|
1559
|
+
} catch {
|
|
1560
|
+
pending = undefined; // the guarded read `JS-1` declares: catch, then classify
|
|
1561
|
+
}
|
|
1562
|
+
if (Object.hasOwn(commit, 'pending') && pending !== undefined) return null;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
return new TypeError(
|
|
1566
|
+
`the write's fifth argument is ${classSpelling(commit)}, and the commit position takes an object `
|
|
1567
|
+
+ 'carrying a `pending` member',
|
|
1568
|
+
);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
export function write(instance, address, tier, value, commit) {
|
|
1364
1572
|
const state = stateOf(instance);
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1573
|
+
let answer;
|
|
1574
|
+
try {
|
|
1575
|
+
// **THE CLASS TEST IS TAKEN BEFORE THE WALK AND BEFORE THE VERB** (`§2.4` item 9 (g) item 1): the
|
|
1576
|
+
// refused position leaves no landing, so the same release the catch block below performs is taken for
|
|
1577
|
+
// an adoption this refusal left unrun (`§2.4` item 9's table row (a) read with `§2.7` item 8).
|
|
1578
|
+
if (arguments.length >= 5) {
|
|
1579
|
+
const refusal = commitPositionRefusal(commit);
|
|
1580
|
+
if (refusal !== null) throw refusal;
|
|
1581
|
+
}
|
|
1582
|
+
const args = arguments.length >= 2 ? [encodeAddress(address)] : [];
|
|
1583
|
+
args.push(encodeTier(tier, arguments.length >= 3, true));
|
|
1584
|
+
// THE WALK'S OWN FAULT RECORD — see `refusedValue`: the walk CLASSIFIES and RECORDS, and the record is
|
|
1585
|
+
// read at the one site where the store answered `ValueNotAdmitted` for a value the walk refused.
|
|
1586
|
+
const fault = { found: null, value: undefined, path: [] };
|
|
1587
|
+
args.push(encodeValue(value, [], 0, [], fault));
|
|
1588
|
+
answer = writeCall(state, args, fault);
|
|
1589
|
+
} catch (refusal) {
|
|
1590
|
+
// **⟶ A WRITE THAT NEVER RAN RELEASES THE ADOPTION IT WAS TAKEN FOR** (`§2.4` item 9's table row (a)
|
|
1591
|
+
// read with `§2.7` item 8, and `PAR-JS-19`'s own keying of one adoption to one write): the adoption
|
|
1592
|
+
// instant (a) took is KEYED TO ONE WRITE and is *"never a queue an unrelated write may draw from"*,
|
|
1593
|
+
// so a `commit` the store refused between instant (a) and the verb — or a walk this boundary refused
|
|
1594
|
+
// before the verb was reached — leaves NO write for that adoption to belong to (`kernel-surface.md
|
|
1595
|
+
// §2.1` item 2: a refused `commit` *"threw BEFORE the write verb ran"*, so no residue exists for any
|
|
1596
|
+
// terminal arm to reach). **IT IS RELEASED HERE AND NOT CARRIED FORWARD**, so the NEXT write reaches
|
|
1597
|
+
// no adoption at all: `§2.7` ITEM 8'S POST-VERB INSTANT FOR A BARE CALLER-MADE WRITE IS UNMOVED BY
|
|
1598
|
+
// ANY KERNEL ACT (`§2.4` item 9 (e); `A116` (D1): the seam withholds *"the write in flight"* and
|
|
1599
|
+
// only it), and an abandoned adoption standing as a pending identity is exactly the withholding this
|
|
1600
|
+
// clause forbids. The store's own refusal crosses back UNCHANGED AND UNCONVERTED.
|
|
1601
|
+
const unrun = state.adopted.size === 0 ? null : state.adopted.values().next().value;
|
|
1602
|
+
if (unrun !== null) {
|
|
1603
|
+
state.adopted.delete(unrun);
|
|
1604
|
+
state.answered.delete(unrun);
|
|
1605
|
+
}
|
|
1606
|
+
throw refusal;
|
|
1607
|
+
}
|
|
1372
1608
|
const record = {
|
|
1373
1609
|
op: decodeJournalOp(answer.op),
|
|
1374
1610
|
watched: answer.watched.map(decodeSegments),
|
|
@@ -1377,7 +1613,64 @@ export function write(instance, address, tier, value) {
|
|
|
1377
1613
|
// **THE INVOCATION WINDOW** (`§2.7` item 2, `DD-22`): the record above is COMPLETE before the window
|
|
1378
1614
|
// opens, the invocation is SYNCHRONOUS, it happens AFTER the addon's call returned, and **its ONE
|
|
1379
1615
|
// argument is the TRIGGERING ADDRESS** (`PAR-JS-12`).
|
|
1380
|
-
|
|
1616
|
+
//
|
|
1617
|
+
// **⟶ AND WHERE THIS WRITE IS ONE `commit` ISSUED, THE WINDOW IS WITHHELD** (`§2.7` items 6–8 with
|
|
1618
|
+
// `§2.4` item 9's instant (a), and `A115` (D2)): the record identity the seam adopted BEFORE this
|
|
1619
|
+
// verb was called stands in `state.withheld`, so this instance invokes NO handle of that write here
|
|
1620
|
+
// and the delivery waits for the pass's terminal arm, where the seam delivers the record's `pending`
|
|
1621
|
+
// residue. **A BARE CALLER-MADE WRITE REACHES NO ADOPTION AND ITS POST-VERB INSTANT STANDS UNMOVED**
|
|
1622
|
+
// (`§2.7` item 8; `§2.4` item 9 (e)): such a record was never passed to the seam, so its set is
|
|
1623
|
+
// delivered exactly as it always was.
|
|
1624
|
+
// **THE ADOPTION IS CONSUMED HERE, AND THE IDENTITY THAT STANDS IN `withheld` IS THIS RECORD'S**
|
|
1625
|
+
// (`§2.4` item 9's table row (a): *"the record identity the instance adopted at instant (a)"*): the
|
|
1626
|
+
// seam marks the write in flight, and this verb — the very write that marker was made for, called by
|
|
1627
|
+
// `commit` on the next statement — is the one write it withholds. **A WRITE THAT FINDS NO ADOPTION IS A
|
|
1628
|
+
// BARE CALLER-MADE WRITE AND ITS POST-VERB INSTANT STANDS UNMOVED** (`§2.7` item 8; `§2.4` item 9 (e)).
|
|
1629
|
+
// **⟶ THE BARE WRITE'S OWN GUARD IS `withheld`, BECAUSE THE MARKER IS THE WITHHOLD AND NOT A
|
|
1630
|
+
// CONSTRUCTION ORDER** (`§2.4` item 9's table row (a): *"WITHHOLDS the package's own delivery for
|
|
1631
|
+
// IT"*; row (b): *"AT THE PASS'S TERMINAL ARM … the SAME record identity"*). **THE ONLY ADOPTION A
|
|
1632
|
+
// KERNEL-DRIVEN WRITE CAN FIND IS ITS OWN**: `settle`'s FIRST call records the identity in BOTH
|
|
1633
|
+
// structures, and the verb that carries that identity DELETES IT FROM `adopted` at `:1438` — so an
|
|
1634
|
+
// entry standing in `adopted` beside a non-empty `withheld` is a second identity, which is another
|
|
1635
|
+
// kernel-driven write's, and this write finds no marker of its own. **ONLY THIS WRITE'S OWN IDENTITY
|
|
1636
|
+
// IS CONSUMED AND ONLY ITS OWN WINDOW IS WITHHELD** — *"A WRITE THAT FINDS NO ADOPTION IS A BARE
|
|
1637
|
+
// CALLER-MADE WRITE AND ITS POST-VERB INSTANT STANDS UNMOVED"* (`§2.7` item 8; `§2.4` item 9 (e)).
|
|
1638
|
+
const pending = state.withheld.size === 0 ? null : state.adopted.values().next().value;
|
|
1639
|
+
// **WHETHER THIS WRITE'S LEDGER ENTRY WAS STILL EMPTY WHEN THE CALL CAME** (`§2.4` item 9 (a)): an
|
|
1640
|
+
// adoption whose own write verb has not yet answered is one a CALLER's own `settle` call may deliver
|
|
1641
|
+
// before the write runs, and it is that delivery the write's own record carries the mark of (`:1456`).
|
|
1642
|
+
const pendingAnswerEmpty = pending !== null && pending !== undefined && state.answered.get(pending) === null;
|
|
1643
|
+
if (pending === null || pending === undefined) {
|
|
1644
|
+
deliver(state, record.triggered, answer.triggeringAddress);
|
|
1645
|
+
} else {
|
|
1646
|
+
state.adopted.delete(pending);
|
|
1647
|
+
state.answered.set(pending, record); // THE IDENTITY THIS ADOPTION'S OWN WRITE RETURNED
|
|
1648
|
+
state.withheld.add(record);
|
|
1649
|
+
// **⟶ AND BOTH IDENTITIES ARE MARKED DELIVERED, BECAUSE THIS WRITE'S DELIVERY HAS NOW HAPPENED**
|
|
1650
|
+
// (`§2.4` item 9: the two instants are counted, and NO third instant is declared — *"there is NO
|
|
1651
|
+
// second adoption"*; `PAR-JS-19`'s domain cell). A delivery taken while the ledger entry stood EMPTY
|
|
1652
|
+
// is a caller's own call and it DELIVERS THIS WRITE'S RESIDUE — the adopted identity `pending` names —
|
|
1653
|
+
// so that identity's occurrence after this instant is no longer a first call, and **THE IDENTITY THE
|
|
1654
|
+
// WRITE RETURNED IS MARKED WITH IT**: `K-2` hands the write's own record to the seam at its terminal
|
|
1655
|
+
// arm, and where the caller took the delivery first, that record arrives with no ledger entry left to
|
|
1656
|
+
// answer it (`state.answered.delete(pending)` above) and would be READ AS A FIRST CALL — adopted, put
|
|
1657
|
+
// in flight a second time, and its marker left standing for a pass that never comes, which withholds
|
|
1658
|
+
// the next bare caller-made write's window (`§2.7` item 8; `§2.4` item 9 (e)). **THE MARK IS TAKEN
|
|
1659
|
+
// ONLY WHERE THE LEDGER ENTRY WAS EMPTY**: an identity delivered at the terminal arm is answered by
|
|
1660
|
+
// the write's own record through `answered`, and marking it there would reach the abandoned attempt's
|
|
1661
|
+
// late arm as a no-op — the delivery the clause owes at that instant (`§2.4` item 9 (b);
|
|
1662
|
+
// `ck_neg_dm_09_*`).
|
|
1663
|
+
if (pendingAnswerEmpty) {
|
|
1664
|
+
state.delivered.add(pending);
|
|
1665
|
+
state.delivered.add(record);
|
|
1666
|
+
}
|
|
1667
|
+
// **AND THE IDENTITY IS THIS WRITE'S FROM HERE ON** (`§2.4` item 9's table row (a): the write *"the
|
|
1668
|
+
// adopted identity names"* is the one its window withholds): a delivery this identity had already
|
|
1669
|
+
// taken — a caller's own call, made while the ledger entry stood EMPTY (`:1735`) — is SUPERSEDED by
|
|
1670
|
+
// the write it belongs to, and the seam's SECOND call for it is the terminal arm's delivery and not
|
|
1671
|
+
// a no-op, so the abandonment's own late arm still reaches the residue (`§2.4` item 9 (b)).
|
|
1672
|
+
state.delivered.delete(record);
|
|
1673
|
+
}
|
|
1381
1674
|
return record;
|
|
1382
1675
|
}
|
|
1383
1676
|
|
|
@@ -1577,6 +1870,214 @@ function registerOn(state, handle, listener) {
|
|
|
1577
1870
|
return undefined;
|
|
1578
1871
|
}
|
|
1579
1872
|
|
|
1873
|
+
/// **THE ORDERING SEAM — `settle(record) -> undefined`** (`surface.md §2.4` item 9; `A116` (D1)–(D4);
|
|
1874
|
+
/// `PAR-JS-19`). The one member the kernel calls and the entry implements, taken at the two instants of a
|
|
1875
|
+
/// kernel-driven write, AND IT REACHES THE REGISTRY AND NOTHING ELSE: no store verb is called, no node is
|
|
1876
|
+
/// minted and no journal entry is appended.
|
|
1877
|
+
///
|
|
1878
|
+
/// * **INSTANT (a) — BEFORE THE STORE'S WRITE VERB IS CALLED.** The identity's FIRST call on this instance
|
|
1879
|
+
/// IS ITS ADOPTION (`PAR-JS-19`'s own domain cell: *"the adoption happens AT the first call and is not
|
|
1880
|
+
/// required before it"*). The record identity is marked as a kernel-driven write in flight, which is
|
|
1881
|
+
/// what makes the write's own post-verb window (`write` above) deliver NOTHING: `§2.4` item 9's table
|
|
1882
|
+
/// row (a), *"WITHHOLDS the package's own delivery for it: the package's post-verb invocation reaches
|
|
1883
|
+
/// NO handle of that write, so its in-window invocation set is EMPTY"*.
|
|
1884
|
+
/// * **INSTANT (b) — AT THE PASS'S TERMINAL ARM.** The SECOND call for that identity IS the delivery: the
|
|
1885
|
+
/// residue standing in the record's `pending` at that instant is iterated through this instance's own
|
|
1886
|
+
/// registry, one invocation per handle, each carrying the TRIGGERING ADDRESS as its single argument
|
|
1887
|
+
/// (`§2.4` item 9's table row (b); `§2.7` items 5 and 7 (a)–(b)). **WHAT IT ITERATES IS THE RESIDUE AND
|
|
1888
|
+
/// NEVER `triggered`**: on a passing attempt the check-off has removed the evaluated pair's entry, and on
|
|
1889
|
+
/// a write that FAILED on constraints the DISCARD has emptied the member — so an empty residue is a
|
|
1890
|
+
/// no-op and not a failure (`§2.7` item 7 (c)–(d)).
|
|
1891
|
+
/// * **EVERY OTHER FORM AT THE RECORD POSITION THROWS THE REGISTRATION SITE'S OWN `TypeError`** — absent,
|
|
1892
|
+
/// `undefined`, `null`, a primitive, a `function`, a `Proxy`, and an identity this instance never
|
|
1893
|
+
/// adopted — **and CHANGES NOTHING** (`§2.4` item 9 (a)–(b); `PAR-JS-19`'s outside-value row).
|
|
1894
|
+
/// * **A RESIDUE HANDLE WITH NO REGISTERED FUNCTION IS A SILENT NO-OP** (`§2.4` rule 1 read at instant
|
|
1895
|
+
/// (b), item 9 (c)): no code, no warning, no log and no throw.
|
|
1896
|
+
function settleOn(state, record, supplied) {
|
|
1897
|
+
// **THE CLASS DECISION COMES FIRST, ON THE VALUE AS IT IS** (`§2.4` item 5 (a)'s order walk;
|
|
1898
|
+
// `crossing.md §1.7`): an absent argument, every non-object and every `Proxy` is refused before any
|
|
1899
|
+
// marker is read or set.
|
|
1900
|
+
if (!supplied || record === null || typeof record !== 'object' || types.isProxy(record)) {
|
|
1901
|
+
throw new TypeError(
|
|
1902
|
+
`settle's argument is ${classSpelling(record)}, and the ordering seam takes a record identity this instance adopted`,
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1905
|
+
// **⟶ ONE WRITE, ONE ADOPTION, AND TWO IDENTITIES CARRY IT** (`§2.4` item 9's table rows (a) and (b);
|
|
1906
|
+
// `PAR-JS-19`: *"the adoption happens AT the first call, and the SECOND call for that identity is the
|
|
1907
|
+
// delivery"*). `K-2` builds its record BEFORE the write verb and hands that identity to the seam at
|
|
1908
|
+
// instant (a); **THE ENTRY'S OWN `write` MINTS THE RECORD IT RETURNS** (`PAR-JS-13`), and that is the
|
|
1909
|
+
// identity this instance puts in flight and whose `pending` member carries the residue the terminal arm
|
|
1910
|
+
// reads. The two calls are ONE identity apart: the arm calls `settle` with the identity it built, and
|
|
1911
|
+
// the ledger entry made at instant (a) carries the write's own record forward to it.
|
|
1912
|
+
//
|
|
1913
|
+
// **THE DOMAIN IS THE INSTANCE'S OWN MARKER AND NOTHING ELSE** (`§2.4` item 9 (a)–(b)): an object this
|
|
1914
|
+
// instance never adopted — *"another instance's record included"* — carries no `pending` member and no
|
|
1915
|
+
// ledger entry, and is refused here with the registration site's own `TypeError`; nothing is set for it.
|
|
1916
|
+
const pre = state.answered.has(record); // this identity is the one a write verb was ADOPTED for
|
|
1917
|
+
const written = pre ? state.answered.get(record) : null;
|
|
1918
|
+
// **AN IDENTITY WHOSE DELIVERY HAS ALREADY HAPPENED SETS NO MARKER** (`§2.4` item 9's two instants,
|
|
1919
|
+
// counted: THE FIRST CALL IS THE ADOPTION and THE SECOND IS THE DELIVERY — *"there is NO second
|
|
1920
|
+
// adoption"*, and no third instant is declared). **THE SECOND CALL REMOVES THE IDENTITY FROM `answered`
|
|
1921
|
+
// AND FROM `adopted`, so its next occurrence arrives with NO LEDGER ENTRY** — and were that occurrence
|
|
1922
|
+
// read as a FIRST call, it would ADOPT, leaving the marker `:1438`'s own deletion never reaches: a
|
|
1923
|
+
// KERNEL-DRIVEN WRITE PUT IN FLIGHT A SECOND TIME, whose window is withheld for a pass that never
|
|
1924
|
+
// comes. **SO A THIRD CALL IS A NO-OP AND CHANGES NOTHING**, which leaves the write that OWNS the
|
|
1925
|
+
// identity as the only act that consumes it, and NO IDENTITY STANDING ADOPTED ON THIS INSTANCE that no
|
|
1926
|
+
// write belongs to — the state the caller-made bare write below reads, which `§2.7` item 8 declares
|
|
1927
|
+
// *"does not move"* whatever stands on the instance (`§2.4` item 9 (e); `PAR-JS-19`).
|
|
1928
|
+
if (!pre && state.delivered.has(record)) {
|
|
1929
|
+
// **AND AN OCCURRENCE AFTER THE TWO DECLARED INSTANTS ENDS ANY IN-FLIGHT STATE STANDING FOR IT**:
|
|
1930
|
+
// a marker is put in flight only by an adoption, and this identity's adoption was consumed (or the
|
|
1931
|
+
// write that would have consumed it never arrived), so the marker this occurrence names is the stale
|
|
1932
|
+
// one the NEXT BARE CALLER-MADE WRITE would otherwise draw on (`§2.4` item 9 (e); `§2.7` item 8).
|
|
1933
|
+
// **NOTHING ELSE CHANGES** — no invocation, no ledger, no residue, and the member's return `undefined`.
|
|
1934
|
+
state.withheld.delete(record);
|
|
1935
|
+
return undefined;
|
|
1936
|
+
}
|
|
1937
|
+
if (!pre) {
|
|
1938
|
+
if (record.pending === undefined) {
|
|
1939
|
+
throw new TypeError(
|
|
1940
|
+
`settle's argument is ${classSpelling(record)}, and the ordering seam takes a record identity this instance adopted`,
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
// INSTANT (a): the adoption. The ledger entry stands EMPTY until the verb answers, so the write that
|
|
1944
|
+
// drains it is the one write identity this adoption is for.
|
|
1945
|
+
state.adopted.add(record);
|
|
1946
|
+
state.answered.set(record, null);
|
|
1947
|
+
// **AND THE IDENTITY IS THE WRITE IN FLIGHT FROM THIS INSTANT** (`§2.4` item 9's table row (a):
|
|
1948
|
+
// *"ADOPTS that identity as a kernel-driven write in flight AND WITHHOLDS the package's own delivery
|
|
1949
|
+
// for it"*): the two structures above carry the LEDGER, and `withheld` is the WITHHOLD ITSELF — the
|
|
1950
|
+
// marker the write verb reads (`:1450`) to know that the delivery of THIS write is not made in its own
|
|
1951
|
+
// window. **BOTH HALVES OF INSTANT (a) ARE TAKEN AT THIS ONE SITE OR NEITHER IS**: without it the
|
|
1952
|
+
// write delivers in-window and the terminal arm's `settle` finds no marker to end. **IT IS SET HERE AND
|
|
1953
|
+
// NOT AT THE VERB, BECAUSE THE SEAM IS CALLED BEFORE THE VERB IS REACHED** (`A116` (D1)).
|
|
1954
|
+
state.withheld.add(record);
|
|
1955
|
+
return undefined;
|
|
1956
|
+
}
|
|
1957
|
+
// **⟶ THE TERMINAL ARM'S OWN ACT, 2026-10-15** (`surface.md §2.11` clause 2; `contract.md §7.2` item 2 as
|
|
1958
|
+
// amended): **on the PASSING arm of a `file`-tier write, the arm PERFORMS THE STORE'S `commit_file` AS
|
|
1959
|
+
// ITS FIRST ACT — BEFORE ANY BODY OF THE DELIVERED SET IS INVOKED** (clause 3 (ii): *"no body before the
|
|
1960
|
+
// save"*; the delivery's one invocation site is `deliver`, below). **Its key is THE SETTLED RECORD'S OWN
|
|
1961
|
+
// `op`** — *"the record the kernel settled carries the journal op that write returned, and that op is the
|
|
1962
|
+
// key this act reads"* — and it is the FIRST THING this arm does, so an arm whose pass FAILED drives no
|
|
1963
|
+
// save and no store call of the write's own at all (clause 1: the lift's scope is the passing arm alone).
|
|
1964
|
+
// **THE ARM IS READ OFF THE MARK THE KERNEL SETS ON ITS PASSING ARM AND OFF NOTHING ELSE**: a `file`-tier
|
|
1965
|
+
// write whose pass failed reaches this same instant, and the act is NOT ITS.
|
|
1966
|
+
//
|
|
1967
|
+
// **A FAILED SAVE IS ANSWERED HERE AND ITS THROW TRAVELS OUT OF THE ARM**: the STORE has already rolled
|
|
1968
|
+
// the write back (`§8.1` #15; clause 5: ROLLBACK FIRST, MESSAGE SECOND) and no body of the delivered set
|
|
1969
|
+
// is reached.
|
|
1970
|
+
//
|
|
1971
|
+
// **⟶ AND THE KERNEL'S OWN HALF OF THIS CELL IS TOLD, ON THE IDENTITY IT HOLDS, 2026-10-15** (`§2.11`
|
|
1972
|
+
// clause 5; `kernel-surface.md §2.1` items 3–5; `fail-surface.md §1.1` item 3): **THE SAVE IS A CONSTRAINT
|
|
1973
|
+
// EVALUATED LAST, AND THE PASS REPORTS ITS FAILURE AS IT REPORTS ANY OTHER** — so the failed save's own
|
|
1974
|
+
// log gains the `outcome` entry, the closed record is the terminal answer and the report carries the
|
|
1975
|
+
// rollback that happened. **THE FAILURE'S OWN CHANNEL IS NOT MOVED BY THIS MARK**: the store's verb
|
|
1976
|
+
// produced it, so its two-member form reaches the caller UNCHANGED (`§1.2` item 2) and NO `log` member and
|
|
1977
|
+
// NO THIRD MEMBER IS ADDED HERE. The mark carries THE VERY THROWABLE — one identity, not a copy — so the
|
|
1978
|
+
// kernel's own catch reads the arm and NOTHING ELSE, and a body of the delivered set that throws (which
|
|
1979
|
+
// this arm never reaches: the throw above leaves the arm first) is never mistaken for the save.
|
|
1980
|
+
if (
|
|
1981
|
+
record[SETTLED_ON_THE_PASSING_ARM] === true
|
|
1982
|
+
&& written !== null
|
|
1983
|
+
&& written.op !== null
|
|
1984
|
+
&& written.op !== undefined
|
|
1985
|
+
&& written.op.tier === 'file'
|
|
1986
|
+
) {
|
|
1987
|
+
try {
|
|
1988
|
+
call(state, 'commitFile', [encodeOpId(written.op.opId)]);
|
|
1989
|
+
} catch (saveFailure) {
|
|
1990
|
+
record[SAVE_FAILED_AT_THE_TERMINAL_ARM] = saveFailure;
|
|
1991
|
+
throw saveFailure;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
// **THE RESIDUE IS READ OFF THE ADOPTED IDENTITY** (`§2.4` item 9 (b)): the write's own record and the
|
|
1995
|
+
// adopted one are ONE WRITE AND ONE RESIDUE — `K-2` fills the member it built from the very set its own
|
|
1996
|
+
// verb returned (`record.pending = written.triggered.slice()`), and it is THAT member the pass checks each
|
|
1997
|
+
// entry off in as it passes (`releasePending`), so the adopted identity is the record whose `pending`
|
|
1998
|
+
// holds the residue AT THIS INSTANT and the write's own record is the identity that was put in flight.
|
|
1999
|
+
// **A SECOND CALL FOR THAT IDENTITY IS THE DELIVERY, WHATEVER THE LEDGER ENTRY HOLDS** (`§2.4` item 9's
|
|
2000
|
+
// table row (b): *"the SECOND call for that identity IS the delivery"* — the ONE clause that decides
|
|
2001
|
+
// this instant; `PAR-JS-19`'s domain cell). **THE EARLY RETURN THIS SITE ONCE SHIPPED — `if
|
|
2002
|
+
// (state.answered.get(record) === null) return undefined;` — WAS A CONSTRUCTION-ORDER DISCRIMINATOR
|
|
2003
|
+
// AND NOT THE CLAUSE'S READING: it asked whether the write verb had answered YET, left the marker
|
|
2004
|
+
// standing, and reached this seam's SECOND call as a no-op.** **A CALLER THAT MADE INSTANT (a)'s CALL
|
|
2005
|
+
// ITSELF — an identity whose write never ran (`§2.4` item 9 (a): *"the RECORD POSITIONS … AND NEVER AN
|
|
2006
|
+
// IDENTITY'S ADOPTION HISTORY"*) — therefore left an adopted identity standing for a write no act
|
|
2007
|
+
// issued, and THE NEXT BARE CALLER-MADE WRITE DREW ON IT: that write's marker was consumed by an
|
|
2008
|
+
// identity that was not its own, its own post-verb window was withheld, and `§2.7` item 8's instant
|
|
2009
|
+
// MOVED for a write the kernel never issued.** **THE DECLARED READING OF THIS CALL IS THE DELIVERY OF
|
|
2010
|
+
// THE IDENTITY'S OWN RESIDUE — the member the RECORD carries at THIS instant** (`§2.4` item 9 (c):
|
|
2011
|
+
// *"A TERMINAL ARM WHOSE RESIDUE CARRIES NO REGISTERED FUNCTION IS A SILENT NO-OP … this member's
|
|
2012
|
+
// return still `undefined`"*) — **AND IT ENDS THE IN-FLIGHT STATE IT TOOK**: the ledger entry goes with
|
|
2013
|
+
// it, so the identity is left adopted by NO write.
|
|
2014
|
+
state.adopted.delete(record);
|
|
2015
|
+
// **AND THE IDENTITY LEAVES `withheld` HERE, WHATEVER THE LEDGER ENTRY HOLDS** (`§2.4` item 9's table
|
|
2016
|
+
// row (b): the delivery *"ends the in-flight state"*, and a second call reaching a write whose verb has
|
|
2017
|
+
// not answered ends it too). **A MARKER THIS CALL LEAVES STANDING IS THE ONE THE NEXT BARE CALLER-MADE
|
|
2018
|
+
// WRITE DRAWS ON** (`§2.4` item 9 (e); `§2.7` item 8) — its window withheld for an act the kernel never
|
|
2019
|
+
// issued — and the identity that marker was taken for is the one this call names.
|
|
2020
|
+
state.withheld.delete(record);
|
|
2021
|
+
// INSTANT (b): the identity leaves the in-flight set and the residue it carries is delivered.
|
|
2022
|
+
state.answered.delete(record);
|
|
2023
|
+
state.withheld.delete(written);
|
|
2024
|
+
// **AND AN IDENTITY'S DELIVERY IS COUNTED WHERE IT HAPPENS, SO THE OCCURRENCES AFTER IT ARE READ AS
|
|
2025
|
+
// NEITHER AN ADOPTION NOR A DELIVERY** (`§2.4` item 9: THE FIRST CALL IS THE ADOPTION AND THE SECOND IS
|
|
2026
|
+
// THE DELIVERY — *"there is NO second adoption"*). **AN EMPTY RESIDUE MARKS NOTHING** (`ck_neg_dm_07_*`
|
|
2027
|
+
// route (i): a caller's first call takes an identity whose `pending` is empty, and its LATER call is
|
|
2028
|
+
// still the delivery that ends it, carrying nothing): the mark is taken by the write's own consumption
|
|
2029
|
+
// of its adoption below (`:1456`), which is the one place both the adopted identity and THE IDENTITY THE
|
|
2030
|
+
// WRITE RETURNED are in hand.
|
|
2031
|
+
// THE DELIVERY THIS CALL MAKES IS STILL THE CLAUSE'S DELIVERY WHATEVER THE LEDGER ENTRY HOLDS.
|
|
2032
|
+
// **THE RESIDUE IS THE MEMBER'S OWN VALUE AT THIS INSTANT** (`§2.7` item 7 (a): *"the handle set that
|
|
2033
|
+
// stands in `CommitRecord.pending` at that instant"*), and each member is the SAME opaque identity this
|
|
2034
|
+
// instance wraps its token as (`§2.3` item 1: handle identity is token equality alone; `§2.4` item 6
|
|
2035
|
+
// (b): the registry's lookup is by THAT identity and by nothing else). **A MEMBER THIS INSTANCE HOLDS
|
|
2036
|
+
// NO HANDLE FOR — the identity a FOREIGN instance minted — is not a member of this registry's key set
|
|
2037
|
+
// and fires nothing silently** (`§2.4` rule 1): this seam writes no entry and mints no identity, so
|
|
2038
|
+
// such a member is passed to `deliver` as it stands and matches no function there.
|
|
2039
|
+
const triggered = Array.isArray(record.pending) ? record.pending.slice() : [];
|
|
2040
|
+
// **⟶ AND BESIDE THE RESIDUE, THE IDENTITIES THE PASS CHECKED OFF WHOSE OWED FIRING STANDS**
|
|
2041
|
+
// (`docs/decisions.md` · `A117` (D5); `surface.md §2.7` item 7's keying of 2026-10-15 and its sub-item
|
|
2042
|
+
// (a)). **THE CHECK-OFF CONSUMES THE EVALUATED PAIR'S OWN DELIVERY OF THAT IDENTITY, NOT THAT
|
|
2043
|
+
// IDENTITY'S WHOLE OWED DELIVERY**: the carrier has ONE entry per address, and the entry's own owed
|
|
2044
|
+
// firings are not counted in `pending` — they are counted where the owed firings live, THIS REGISTRY.
|
|
2045
|
+
// So an identity whose pair the pass evaluated and checked off is NOT an identity with no owed firing,
|
|
2046
|
+
// and where this registry still holds a function for it the terminal arm delivers it ONCE, exactly as
|
|
2047
|
+
// the residue's own members are delivered (`§2.7` item 6 — the other listeners are reached ONCE every
|
|
2048
|
+
// constraint has passed — read with `§2.4` item 8 (c) AS CORRECTED 2026-10-15: *"the app's registration
|
|
2049
|
+
// at a pair-adopted address IS OWED ITS FIRING AFTER THE PASS"*).
|
|
2050
|
+
//
|
|
2051
|
+
// **THIS IS NOT A SECOND CHANNEL**: the resolution is the SAME ONE the residue is delivered by — this
|
|
2052
|
+
// registry's lookup by the identity alone — and it is the resolution that DECIDES the arm, so an
|
|
2053
|
+
// identity the registry holds no function for fires NOTHING SILENTLY, exactly as a residue member with
|
|
2054
|
+
// no function does (`§2.4` rule 1; item 9 (c)). **NO MEMBER IS ADDED ANYWHERE** (`A117` (D6)): the
|
|
2055
|
+
// finding is the kernel's own, carried on the record under a SYMBOL key, and `record.pending` — the
|
|
2056
|
+
// member the residue's own assertions read — stands EXACTLY as the check-off left it (the returned set
|
|
2057
|
+
// minus the checked-off entries and minus nothing else). **AND ON A FAILING WRITE NOTHING IS
|
|
2058
|
+
// DELIVERED**: the kernel publishes no such list on that arm, and its residue stands empty by the
|
|
2059
|
+
// discard (`§2.7` item 7 (d); `A114` (D1)/(D2)).
|
|
2060
|
+
const checkedOff = record[CHECKED_OFF];
|
|
2061
|
+
if (Array.isArray(checkedOff)) {
|
|
2062
|
+
for (const handle of checkedOff) {
|
|
2063
|
+
if (!triggered.includes(handle)) triggered.push(handle);
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
// **THE INVOCATION'S ONE ARGUMENT IS THE TRIGGERING ADDRESS** (`§2.7` item 5): the address the
|
|
2067
|
+
// trigger's own op landed at, read off the op the record carries — the OP's address and never the
|
|
2068
|
+
// registration's watch address (`kernel-surface.md §2.1` item 2 (ii)).
|
|
2069
|
+
// **A SECOND CALL ARRIVING BEFORE THE WRITE VERB HAS ANSWERED CARRIES NO OP, AND ITS ADDRESS IS
|
|
2070
|
+
// `undefined` BESIDE IT** (`written` is the ledger entry and it stands EMPTY at instant (a)): the record
|
|
2071
|
+
// carries no op yet, and `§2.7` item 5's argument is the OP's own address or nothing.
|
|
2072
|
+
const triggeringAddress = written === null || written.op === null || written.op === undefined
|
|
2073
|
+
? undefined
|
|
2074
|
+
: written.op.address;
|
|
2075
|
+
// `deliver` is THE SAME loop the post-verb window uses (`§2.4` rules 1–3 read once, at both instants):
|
|
2076
|
+
// ONE invocation per DISTINCT handle, and a handle with no registered function fires nothing silently.
|
|
2077
|
+
deliver(state, triggered, triggeringAddress);
|
|
2078
|
+
return undefined;
|
|
2079
|
+
}
|
|
2080
|
+
|
|
1580
2081
|
// ---------------------------------------------------------------------------------------------
|
|
1581
2082
|
// THE TWO NEW INSTANCE MEMBERS — `surface.md §2.4` ITEM 7, READ AT ITS OWN BYTES, AND `§2.1`'s DATED
|
|
1582
2083
|
// CLAUSE (a): `on(address, listener) -> handle` AND `off(handle) -> undefined`, BESIDE `register`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "provident-storeroom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "U-STOREROOM-PUBLISH: the published Node ESM binding for the native Rust store of Provident-Storeroom — the entry resolves the scoped per-target platform package first, the checkout's own module-relative addon second, and answers the store's single declared absent-addon form when neither loads",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"index.d.ts"
|
|
37
37
|
],
|
|
38
38
|
"optionalDependencies": {
|
|
39
|
-
"@auspicion/provident-storeroom-js-linux-x64-gnu": "0.
|
|
40
|
-
"@auspicion/provident-storeroom-js-linux-arm64-gnu": "0.
|
|
41
|
-
"@auspicion/provident-storeroom-js-darwin-x64": "0.
|
|
42
|
-
"@auspicion/provident-storeroom-js-darwin-arm64": "0.
|
|
43
|
-
"@auspicion/provident-storeroom-js-win32-x64-msvc": "0.
|
|
39
|
+
"@auspicion/provident-storeroom-js-linux-x64-gnu": "0.2.0",
|
|
40
|
+
"@auspicion/provident-storeroom-js-linux-arm64-gnu": "0.2.0",
|
|
41
|
+
"@auspicion/provident-storeroom-js-darwin-x64": "0.2.0",
|
|
42
|
+
"@auspicion/provident-storeroom-js-darwin-arm64": "0.2.0",
|
|
43
|
+
"@auspicion/provident-storeroom-js-win32-x64-msvc": "0.2.0"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|