provident-storeroom 0.0.0-stage → 0.1.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 +165 -2
- package/index.d.ts +257 -0
- package/index.mjs +1849 -0
- package/package.json +38 -4
package/README.md
CHANGED
|
@@ -1,3 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `provident-storeroom` — the published Node ESM binding for the native Rust store
|
|
2
|
+
|
|
3
|
+
**THE CLAIMED REALM IS `{ Node ESM }` AND NOTHING ELSE** (`A70`, `package.md §1.1`): a consumer `import`s
|
|
4
|
+
this package as an ES module from a Node runtime whose ABI carries a Node-API addon. **Every other realm is
|
|
5
|
+
UNCLAIMED and each owes its declared answer** (`package.md §2`: Node CJS, Electron `main`, Electron
|
|
6
|
+
`preload`, Electron `renderer`, the browser, `worker_threads` and any IPC route). **No other realm is
|
|
7
|
+
described here as supported.**
|
|
8
|
+
|
|
9
|
+
**THE LICENCE OF RECORD IS `AGPL-3.0`** (`DD-43`). It is the repository's own `LICENSE` and no clause of
|
|
10
|
+
this unit changes it. **AND THE LICENCE COPY TRAVELS WITH EVERY ARTEFACT, THIS PACKAGE'S OWN INCLUDED**:
|
|
11
|
+
each of the SIX artefacts — this package and the five platform packages — carries a copy of the
|
|
12
|
+
repository's own `LICENSE` as the licence TEXT travelling with it, copied BYTE-FOR-BYTE at the release's
|
|
13
|
+
own assembly step (`docs/specs/storeroom-publish/contract.md §2.3` item 2; `distribution.md §4.2` item 1 and
|
|
14
|
+
`§4.3` item 2; `PUB-DD-11`; `Q3-5`). **WHAT IS REFUSED IS A SECOND, DRIFTING COPY INSIDE THE TREE**: no
|
|
15
|
+
`LICENSE` byte is written under `bindings/js/` (`§2.3` item 4; `distribution.md §4.3` item 1), so the copy
|
|
16
|
+
is an ARTEFACT-LEVEL fact and not a crate-level file, and this package's `files` allowlist names it
|
|
17
|
+
nowhere — the allowlist is the three entries `§2.1` item 1 fixes and NOTHING ELSE (`Q3-2`). **AND THE COPY
|
|
18
|
+
IS NOT A FIFTH DECLARATION SITE** (`distribution.md §4.2` item 3): the four sites are AUTHORED
|
|
19
|
+
DECLARATIONS ABOUT the licence, while a tarball's own copy is the licence's text travelling with an
|
|
20
|
+
artefact — so the count of SITES stays four and the count of artefacts CARRYING A NOTICE is six.
|
|
21
|
+
|
|
22
|
+
## The one entry
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import { storeCreate, read, readLiteral, write, delete as remove, rollback, listen, unlisten } from 'provident-storeroom';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**The `exports` map publishes EXACTLY ONE arms-bearing entry — the ESM one** (`package.md §1.3`, `DD-24`):
|
|
29
|
+
there is no wildcard export, no deep import to the addon and no CJS arm. **The addon is reached INTERNALLY
|
|
30
|
+
by the package's own `createRequire`-style step and is not an entry point**: a consumer that spells the
|
|
31
|
+
addon's path directly is outside every clause of this contract.
|
|
32
|
+
|
|
33
|
+
## The surface
|
|
34
|
+
|
|
35
|
+
**The eight verbs of `surface.md §2` and NOTHING ELSE**, plus the one member of the object `storeCreate`
|
|
36
|
+
returned:
|
|
37
|
+
|
|
38
|
+
| The member | Its answer |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `storeCreate(cfg)` | the package's own instance handle — `cfg` carries the store's three declared keys and no fourth |
|
|
41
|
+
| `read(instance, address, tier?)` | a leaf's literal, a branch's assembled value, the empty address's whole register |
|
|
42
|
+
| `readLiteral(instance, address, tier?)` | the same, narrowed to a leaf (`ReadTargetIsBranch` on a branch) |
|
|
43
|
+
| `write(instance, address, tier, value)` | `{op, watched, triggered}` |
|
|
44
|
+
| `delete(instance, address, tier?)` | `{address, tiers, triggered}` |
|
|
45
|
+
| `rollback(instance, opId)` | `{opId, undoneOps, restoredTo}` |
|
|
46
|
+
| `listen(instance, address)` | a fresh opaque handle |
|
|
47
|
+
| `unlisten(instance, handle)` | `undefined` — and a no-op success for every value outside the domain |
|
|
48
|
+
| `instance.register(handle, listener)` | `undefined`; a non-function listener or a handle this instance never minted throws a `TypeError` |
|
|
49
|
+
|
|
50
|
+
**The failure form is ONE** (`surface.md §2.5`, `DD-12`): a THROWN plain object carrying exactly
|
|
51
|
+
`{status, message}` — never an `Error` subclass, never a returned tagged union and never a `Promise`.
|
|
52
|
+
**No `findAddress` is exposed** (`A63`), no `exists` verb exists and no release verb is declared (`A74`).
|
|
53
|
+
|
|
54
|
+
## The two readings a caller will meet, and the reload rule
|
|
55
|
+
|
|
56
|
+
**A handle MUST NOT be carried across a process reload.** Handle identity is this process's own: a prior
|
|
57
|
+
session's token names no registration of this process, and `unlisten` over it is a no-op success while
|
|
58
|
+
`register` over it is a `TypeError`.
|
|
59
|
+
|
|
60
|
+
**Two file-behaviour readings.** A `delete` and a `rollback` perform no file I/O, so a consumer that deletes
|
|
61
|
+
a `file`-tier version and then constructs a fresh instance over an equal `filePath` sees the removed version
|
|
62
|
+
STAND AGAIN — that re-boot is the store's own declared boot and not a defect. And a `file`-tier `write` that
|
|
63
|
+
fails answers `FileCommitFailed` after the store's own automatic journal rollback has run; the package
|
|
64
|
+
compensates for nothing.
|
|
65
|
+
|
|
66
|
+
## How the addon is resolved — three rungs, and the covered/uncovered answer
|
|
67
|
+
|
|
68
|
+
**THE ENTRY RESOLVES ITS ARTEFACT IN THE DECLARED ORDER** (`docs/specs/storeroom-publish/resolution.md
|
|
69
|
+
§2`; `docs/specs/storeroom-publish/contract.md §1.1`):
|
|
70
|
+
|
|
71
|
+
1. **RUNG ONE — THE SCOPED PLATFORM PACKAGE FOR THIS RUNTIME'S KEY.** The entry `require`s THE ONE NAME
|
|
72
|
+
the closed key set declares for the `process.platform` × `process.arch` pair, and no other name. The
|
|
73
|
+
five declared names are
|
|
74
|
+
|
|
75
|
+
**`@auspicion/js-linux-x64-gnu`** · **`@auspicion/js-linux-arm64-gnu`** ·
|
|
76
|
+
**`@auspicion/js-darwin-x64`** · **`@auspicion/js-darwin-arm64`** ·
|
|
77
|
+
**`@auspicion/js-win32-x64-msvc`**
|
|
78
|
+
|
|
79
|
+
— five names, three of them carrying a toolchain suffix (`-gnu` twice, `-msvc` once) and two carrying
|
|
80
|
+
none. **The name is SELECTED from this table and is never built by concatenating tokens**, so no sixth
|
|
81
|
+
name is computed. These five are the registry's own per-target optional dependencies, and this
|
|
82
|
+
package's `optionalDependencies` pins each of them at this package's own version, exactly.
|
|
83
|
+
|
|
84
|
+
2. **RUNG TWO — THE MODULE-RELATIVE ADDON.** Failing rung one, the entry `require`s
|
|
85
|
+
`build/Release/storeroom_js_binding.node` beside the entry module, constructed from the entry module's
|
|
86
|
+
own location and from no other source — no environment variable, no configuration key, no path
|
|
87
|
+
relative to the working directory and no search of a parent directory.
|
|
88
|
+
|
|
89
|
+
3. **RUNG THREE — THE DECLARED ABSENT-ADDON FORM.** Failing rung two, the load path answers the single
|
|
90
|
+
failure form, and no instance is returned.
|
|
91
|
+
|
|
92
|
+
**IN A PUBLISHED INSTALL, RUNG ONE IS THE RUNG THAT FIRES**, because rung two's path is the checkout's
|
|
93
|
+
own and a `files`-restricted tarball does not carry it — **no binary ships IN THIS PACKAGE'S OWN TARBALL,
|
|
94
|
+
at any key, on any target** (`§2.1` item 1; `Q3-2`). **AND THE FIVE PLATFORM ARTEFACTS EACH CARRY THEIR OWN
|
|
95
|
+
TARGET'S BINARY**: each one's allowlist names the `.node` beside its manifest, which is what gives rung one
|
|
96
|
+
a declared source to load at that key at all (`PAR-PUB-21`; `distribution.md §3.2` item 5). **RUNG TWO IS
|
|
97
|
+
THE CHECKOUT-ONLY RUNG**: it is the in-place developer loop and every battery that exists today, and
|
|
98
|
+
building it is a step of a checkout rather than of an install:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
cargo build --release --manifest-path bindings/js/Cargo.toml --offline
|
|
102
|
+
mkdir -p bindings/js/build/Release
|
|
103
|
+
cp bindings/js/target/release/libstoreroom_js_binding.so bindings/js/build/Release/storeroom_js_binding.node
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**No binary is ever committed** (`package.md §3.2`): `build/` and `target/` are ignored, and the artefacts
|
|
107
|
+
are built and published, never stored in the tree. **The prebuild matrix is five targets** (`linux-x64`,
|
|
108
|
+
`linux-arm64`, `darwin-x64`, `darwin-arm64`, `win32-x64`), built one runner per target by the release's own
|
|
109
|
+
workflow, `/.github/workflows/publish.yml`. The Node-API version this addon is built against is the sibling
|
|
110
|
+
crate's own build target and is not a JS-side floor of this package's own (`package.md §1.4`).
|
|
111
|
+
|
|
112
|
+
**AND THE UNCOVERED-TARGET ANSWER IS A DECLARED LIMITATION, WITH ITS CONSEQUENCE STATED RATHER THAN
|
|
113
|
+
DISCOVERED** (`docs/specs/storeroom-publish/contract.md §2.1` item 3; `docs/specs/storeroom-publish/
|
|
114
|
+
distribution.md §2.2`; `PUB-DD-1`, `PUB-DD-2`):
|
|
115
|
+
|
|
116
|
+
* **A CONSUMER WHOSE `process.platform` × `process.arch` PAIR IS NOT ONE OF THE FIVE COVERED KEYS GETS NO
|
|
117
|
+
BINARY.** Rung one is not attempted at all for that pair — no name exists for it — so the load path
|
|
118
|
+
falls to rung two, which a published install does not carry, and the uncovered consumer therefore meets
|
|
119
|
+
the declared absent-addon form.
|
|
120
|
+
* **THEY GET NO BUILDABLE ROUTE FROM THE TARBALL EITHER: no `build.rs`, no `Cargo.toml`, no `src/**` and
|
|
121
|
+
no `postinstall` build-on-install step is shipped.** The store crate's source is deliberately outside
|
|
122
|
+
this package's allowlist, whose whole content is `index.mjs` · `README.md` · `index.d.ts`.
|
|
123
|
+
* **THEIR ONLY ROUTE IS TO BUILD THE STORE CRATE FROM ITS SOURCE THEMSELVES.** This is a LIMITATION and
|
|
124
|
+
not a promise: no clause of this package claims that an uncovered consumer's route is supported, tested
|
|
125
|
+
or witnessed. **A covered consumer needs NO Rust toolchain; an uncovered consumer needs one.**
|
|
126
|
+
* **AND THE DECLARED ANSWER TO A COVERED KEY WHOSE C LIBRARY DIFFERS FROM ITS ARTEFACT'S IS THE SAME
|
|
127
|
+
ONE**: the `os` and `cpu` fields carry an operating system and an architecture and cannot express a C
|
|
128
|
+
library, so no C library is read, detected or measured anywhere on this load path, and a state that
|
|
129
|
+
follows from that is a state the load path reaches rather than a key of its own.
|
|
130
|
+
|
|
131
|
+
## Tests
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
cargo test --manifest-path bindings/js/Cargo.toml --offline --no-fail-fast # the sibling crate's Rust tests
|
|
135
|
+
node --test bindings/js/test/*.test.mjs # this package's JS tests
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**AND THE ORDER IS A DECLARED STEP, NOT A CONVENIENCE: THE JS LEG RUNS ONLY AFTER THE ADDON IS BUILT**
|
|
139
|
+
(`docs/specs/storeroom-js-proposal.md §17` · `A75`: *"the JS leg of the acceptance layer acquires A BUILD
|
|
140
|
+
STEP (a `.node` must exist for those cells)"*). **The JS cells drive the package through its CLAIMED ESM
|
|
141
|
+
ENTRY and never the `.node` addon directly** (`acceptance.md §4.1` item 1, `DD-18`), so the entry's own
|
|
142
|
+
route — `JS -> facade -> core -> store` — is what they exercise, and that route needs the artefact the
|
|
143
|
+
`Building the addon` section above produces:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
# 1. THE BUILD STEP, AT THE REPOSITORY ROOT, BEFORE ANY JS CELL RUNS:
|
|
147
|
+
cargo build --release --manifest-path bindings/js/Cargo.toml --offline
|
|
148
|
+
mkdir -p bindings/js/build/Release
|
|
149
|
+
cp bindings/js/target/release/libstoreroom_js_binding.so bindings/js/build/Release/storeroom_js_binding.node
|
|
150
|
+
# 2. THE JS LEG, AFTER IT:
|
|
151
|
+
node --test bindings/js/test/*.test.mjs
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**THERE IS NO FALLBACK AND NO JS-SIDE STORE** (`A75`): an addon that is ABSENT or FAILS TO LOAD is a
|
|
155
|
+
**DECLARED FAILURE** — `storeCreate` answers the single failure form
|
|
156
|
+
`{status: 'FilePathUnreachable', message: <the store's own generated string at the addon's path>}` and NO
|
|
157
|
+
instance is returned. **AND THE MESSAGE'S OWN STRING IS NOT A PLACEHOLDER** (`JS-3`, closed): it is the
|
|
158
|
+
store's generator's rendering of THAT subject — `'/abs/path/to/build/Release/storeroom_js_binding.node' is
|
|
159
|
+
not reachable at construction, the path must exist or the application must be able to write it` — reached
|
|
160
|
+
through the addon's `errorMessage` where the artefact loaded far enough to carry the generator, and
|
|
161
|
+
reproduced BYTE-FOR-BYTE from the generator's own clause (`src/error.rs`'s `FilePathUnreachable` arm) where
|
|
162
|
+
the generator is the thing that failed to load. **A consumer that runs the JS cells without step 1 sees that
|
|
163
|
+
failure and not a silently degraded run.** **The Rust leg needs no addon at all**: the conversion core is the
|
|
164
|
+
crate's `rlib` half, so `cargo test --manifest-path bindings/js/Cargo.toml` is drivable with no Node runtime
|
|
165
|
+
present (`package.md §4.1` item 3, `§4.5` item 7).
|
|
2
166
|
|
|
3
|
-
This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// `provident-storeroom` — **THE AUTHORED TYPE DECLARATION OF THE PUBLISHED NODE ESM BINDING**
|
|
2
|
+
// (`docs/specs/storeroom-publish/contract.md §2.4`; `docs/specs/storeroom-publish/distribution.md §5`;
|
|
3
|
+
// `PUB-DD-3`; `Q3-4`).
|
|
4
|
+
//
|
|
5
|
+
// **THIS FILE IS HAND-AUTHORED AND NOT GENERATED** (`§2.4` item 1; `PUB-DD-21`): it carries no generation
|
|
6
|
+
// banner, no build-time code generator produces it, and it is the file the package's own `types` field
|
|
7
|
+
// reaches and the package's own `files` allowlist ships.
|
|
8
|
+
//
|
|
9
|
+
// **IT DECLARES THREE THINGS AND NOTHING ELSE** (`distribution.md §5.2`): (1) the EIGHT VERBS of the
|
|
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 }` — three own members and nothing else; and (3) the
|
|
12
|
+
// failure surface, a thrown plain object with exactly `{status, message}`.
|
|
13
|
+
//
|
|
14
|
+
// **AND THE RECORDS THOSE VERBS ANSWER WITH ARE DECLARED BESIDE THEM, WHICH IS STILL PART (1) AND NOT A
|
|
15
|
+
// FOURTH THING**: `Address` · `Tier` · `TierSet` · `StoreConfig` · `BaseState` · `JournalOp` ·
|
|
16
|
+
// `WriteRecord` · `DeleteRecord` · `RollbackRecord` · `Handle` · `Listener` are the SHAPES OF THE
|
|
17
|
+
// ARGUMENTS AND OF THE ANSWERS, in `DD-39`'s own member spellings (the sibling directory's `contract.md
|
|
18
|
+
// §0.2`), and a declaration that did not carry them would declare eight names and no surface. **None of
|
|
19
|
+
// them is a STORE type**: no register, no anchor, no tier tree, no journal and no store verb is declared
|
|
20
|
+
// here (`§5.2` item 4).
|
|
21
|
+
//
|
|
22
|
+
// **AND THE ONE THING THIS DECLARATION MUST NOT CARRY, STATED SO THE FINDING RULE IS CHECKABLE**
|
|
23
|
+
// (`distribution.md §5.2` item 4): **it declares NO store type, NO store verb, NO `findAddress`, NO
|
|
24
|
+
// release verb and NO constraint or repair seam** — each of those is a declaration the sibling directory
|
|
25
|
+
// refuses, and a declaration file carrying one would declare a surface the package does not publish.
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A position in the register: the address a verb is called at, as a sequence of path segments.
|
|
29
|
+
*
|
|
30
|
+
* **A SEGMENT IS A `string` (a key) OR A NON-NEGATIVE INTEGER (an index)** — `PAR-JS-5`'s own domain, and the
|
|
31
|
+
* domain the shipped walk admits and the store's own records return. **`readonly string[]` WAS THE SHIPPED
|
|
32
|
+
* DECLARATION AND IS FALSE OF EVERY ADDRESS CARRYING AN INDEX**, so a consumer compiling the lawful
|
|
33
|
+
* `read(instance, ['key', 0])` met a type error on a correct call.
|
|
34
|
+
*/
|
|
35
|
+
export type Address = readonly (string | number)[];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The tier a verb is called at: the store's own persistence tokens.
|
|
39
|
+
*
|
|
40
|
+
* **THE DOMAIN IS THE STORE'S THREE TOKENS — `'mem'` · `'file'` · `'temp'`** (`PAR-JS-6` · `PAR-JS-7` ·
|
|
41
|
+
* `PAR-JS-11`; the store's own tier row). **`'mem' | 'file'` WAS THE SHIPPED DECLARATION AND DROPPED
|
|
42
|
+
* `'temp'`**, mis-typing a lawful third token as a value outside the domain.
|
|
43
|
+
*/
|
|
44
|
+
export type Tier = 'mem' | 'file' | 'temp';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* **THE READER'S ARITY, DECLARED BECAUSE IT IS NOT THE WRITER'S** (`PAR-JS-6`; `crossing.md §1.3`'s
|
|
48
|
+
* `TierArg` row 2): on `read` and `readLiteral` a tier is ABSENT, ONE token, or an ARRAY of tokens read as an
|
|
49
|
+
* ANY-MATCH set. **On `write` and `delete` an array is outside the domain — the array spelling is the
|
|
50
|
+
* reader's arity — so those two verbs take the single token `Tier` alone** (`PAR-JS-7` · `PAR-JS-11`).
|
|
51
|
+
*/
|
|
52
|
+
export type TierSet = Tier | readonly Tier[];
|
|
53
|
+
|
|
54
|
+
/** The configuration a store is constructed from — the store's three declared keys and no fourth. */
|
|
55
|
+
export interface StoreConfig {
|
|
56
|
+
/** The journal's declared length: a positive integer (`PAR-JS-3`). */
|
|
57
|
+
readonly journalLength: number;
|
|
58
|
+
/**
|
|
59
|
+
* The listeners a construction adopts (`PAR-JS-4`): an array of `{ address, handle }` records, the EMPTY
|
|
60
|
+
* array included.
|
|
61
|
+
*
|
|
62
|
+
* **AND THE KEY IS REQUIRED, NOT OPTIONAL**: an ABSENT `listeners` is the ONE absence the construction
|
|
63
|
+
* does not admit and answers `AddressMalformed` for, so `listeners?` — the shipped spelling — invited a
|
|
64
|
+
* call that can never construct. **The ELEMENT SHAPE IS THE STORE'S TO REFUSE**: a member that is not an
|
|
65
|
+
* `{ address, handle }` record, or whose `handle` is not a plain non-empty `string`, is admitted here and
|
|
66
|
+
* refused by the store's own construction, because the package mints no second refusal for that position.
|
|
67
|
+
*/
|
|
68
|
+
readonly listeners: readonly unknown[];
|
|
69
|
+
/** The file the file tier is backed by, where one is declared (`PAR-JS-2`; ABSENT is in domain). */
|
|
70
|
+
readonly filePath?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* **THE STORE'S OWN CLOSED SET OF FAILURE CODES, AS THE TYPE DECLARES IT — A UNION OVER A
|
|
75
|
+
* DECLARED-BUT-OPEN SET** (`contract.md §2.4` item 2; `distribution.md §5.3`; `PUB-DD-3`).
|
|
76
|
+
*
|
|
77
|
+
* **THE FIFTEEN MEMBERS BELOW ARE THE STORE'S OWN, and their membership is the STORE'S to close and
|
|
78
|
+
* never this package's**: this package MINTS NO MEMBER, WIDENS NO SET AND RENAMES NONE
|
|
79
|
+
* (`distribution.md §5.3` item 3).
|
|
80
|
+
*
|
|
81
|
+
* **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 members and the store's own park prices a sixteenth, so an
|
|
83
|
+
* immutably-enumerated union would mis-type a LAWFUL refusal the moment the store's set moves
|
|
84
|
+
* (`PUB-DD-3`'s refused alternative). The `(string & {})` arm is what keeps a member the store has added
|
|
85
|
+
* typeable in an installed `0.1.0`, and its absence would be a finding rather than a strictness.
|
|
86
|
+
*/
|
|
87
|
+
export type StoreStatus =
|
|
88
|
+
| 'AddressMalformed'
|
|
89
|
+
| 'AddressNotFound'
|
|
90
|
+
| 'LeafHasNoDownstream'
|
|
91
|
+
| 'TierNotFound'
|
|
92
|
+
| 'OutOfDomainTier'
|
|
93
|
+
| 'ParentAnchorMonotonicityViolation'
|
|
94
|
+
| 'ContainerKindConflict'
|
|
95
|
+
| 'ReadTargetIsBranch'
|
|
96
|
+
| 'WriteParentNotLink'
|
|
97
|
+
| 'JournalOpUnknown'
|
|
98
|
+
| 'RollbackCompacted'
|
|
99
|
+
| 'ConstructionArgumentMissing'
|
|
100
|
+
| 'FilePathUnreachable'
|
|
101
|
+
| 'ValueNotAdmitted'
|
|
102
|
+
| 'FileCommitFailed'
|
|
103
|
+
| (string & {});
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* **THE SINGLE FAILURE SURFACE** (`contract.md §1.4`; `distribution.md §5.2` item 3): a THROWN plain
|
|
107
|
+
* object carrying exactly `{status, message}` — never an `Error` subclass, never a returned tagged union,
|
|
108
|
+
* never a `Promise` rejection and never a third member. **The status is carried VERBATIM from the store's
|
|
109
|
+
* own closed set and the message is the store's own generated string**; this package mints neither.
|
|
110
|
+
*/
|
|
111
|
+
export interface StoreRefusal {
|
|
112
|
+
readonly status: StoreStatus;
|
|
113
|
+
readonly message: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** The opaque handle a listener registration is keyed by: the package's own value for one registration. */
|
|
117
|
+
export type Handle = object;
|
|
118
|
+
|
|
119
|
+
/** The caller's listener: any JS function, invoked with the triggering address as its ONE argument. */
|
|
120
|
+
export type Listener = (address: Address) => void;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* **A BASE STATE — THE PRE- AND POST-STATE A JOURNAL OP CARRIES** (`DD-39`: *"`BaseState` → `{ present,
|
|
124
|
+
* value }`"*). **`present` is whether a version stood at the address, and `value` is that version's value
|
|
125
|
+
* where one did — `undefined` where none did**, because the record is the store's own and the package adds
|
|
126
|
+
* no member to it.
|
|
127
|
+
*/
|
|
128
|
+
export interface BaseState {
|
|
129
|
+
readonly present: boolean;
|
|
130
|
+
readonly value: unknown;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* **THE STORE'S OWN JOURNAL OP, CROSSED MEMBER FOR MEMBER AND IN THE STORE'S OWN SPELLINGS** — `DD-39`'s
|
|
135
|
+
* eight declared names (`distribution.md §5.2` item 1; `P-PUB-7`): `{ opId, kind, address, tier, before,
|
|
136
|
+
* after, seq, compacted }`.
|
|
137
|
+
*
|
|
138
|
+
* **`opId` IS A `string`** — the store's own op-id domain is a non-empty string (`PAR-JS-9`), and the id a
|
|
139
|
+
* `write` returns is the id a `rollback` takes. **`kind` is the store's own token** (`'write'` and
|
|
140
|
+
* `'delete'` today) **and its membership is the STORE'S to close, so it is typed as `string` and this
|
|
141
|
+
* package mints no union over it.** **`tier` is one of the store's own three tokens, or `null` where the op
|
|
142
|
+
* carries none**; **`seq` is the journal's own sequence number and `compacted` the store's own flag**, each
|
|
143
|
+
* carried verbatim.
|
|
144
|
+
*/
|
|
145
|
+
export interface JournalOp {
|
|
146
|
+
readonly opId: string;
|
|
147
|
+
readonly kind: string;
|
|
148
|
+
readonly address: Address;
|
|
149
|
+
readonly tier: Tier | null;
|
|
150
|
+
readonly before: BaseState;
|
|
151
|
+
readonly after: BaseState;
|
|
152
|
+
readonly seq: number;
|
|
153
|
+
readonly compacted: boolean;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* The record a `write` answers: fresh data on every call, never a view of the store's own state.
|
|
158
|
+
*
|
|
159
|
+
* **`op` IS THE STORE'S OWN JOURNAL RECORD AND NOT A NUMBER** (`DD-39`; `P-PUB-7`'s `S-TYPES`): **the shipped
|
|
160
|
+
* declaration read `op: number`, which is false of EVERY value the line returns**, and a consumer compiling
|
|
161
|
+
* `write(i, a, 'mem', v).op.opId` met a type error on a correct call.
|
|
162
|
+
*/
|
|
163
|
+
export interface WriteRecord {
|
|
164
|
+
readonly op: JournalOp;
|
|
165
|
+
readonly watched: readonly Address[];
|
|
166
|
+
readonly triggered: readonly Handle[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** The record a `delete` answers. */
|
|
170
|
+
export interface DeleteRecord {
|
|
171
|
+
readonly address: Address;
|
|
172
|
+
readonly tiers: readonly Tier[];
|
|
173
|
+
readonly triggered: readonly Handle[];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* The record a `rollback` answers (`DD-39`: *"`RollbackResult` → `{ opId, undoneOps, restoredTo }`"*).
|
|
178
|
+
*
|
|
179
|
+
* **ALL THREE MEMBERS WERE MISTYPED BY THE SHIPPED DECLARATION** (`opId: number`, `undoneOps: number`,
|
|
180
|
+
* `restoredTo: number`): **`opId` echoes the id the caller passed, and that id is a `string`** (`PAR-JS-9`'s
|
|
181
|
+
* own unit: *"the `JournalOp.opId` string"*); **`undoneOps` is the LIST of the ids the reversal undid — an
|
|
182
|
+
* ARRAY of those ids, not a count**; and **`restoredTo` is the base state the addressed subtree now stands
|
|
183
|
+
* at**, `{ present, value }`.
|
|
184
|
+
*/
|
|
185
|
+
export interface RollbackRecord {
|
|
186
|
+
readonly opId: string;
|
|
187
|
+
readonly undoneOps: readonly string[];
|
|
188
|
+
readonly restoredTo: BaseState;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* **THE INSTANCE `storeCreate` RETURNS — `{ register, on, off }`, THREE OWN MEMBERS AND NOTHING ELSE**
|
|
193
|
+
* (`distribution.md §5.2` item 2). **The instance's own state is released with the instance and by nothing
|
|
194
|
+
* else: none of the three is a release verb.**
|
|
195
|
+
*/
|
|
196
|
+
export interface StoreInstance {
|
|
197
|
+
/** Register `listener` under the opaque `handle`, and answer `undefined`. */
|
|
198
|
+
register(handle: Handle, listener: Listener): void;
|
|
199
|
+
/** Register a listener at `address` and answer the fresh opaque handle it is keyed by. */
|
|
200
|
+
on(address: Address, listener: Listener): Handle;
|
|
201
|
+
/** Withdraw the store-side home entry the `handle` names, and answer `undefined`. */
|
|
202
|
+
off(handle: Handle): void;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Construct a store at `cfg` and answer its instance.
|
|
207
|
+
*
|
|
208
|
+
* **AN ADDON THAT IS ABSENT, THAT FAILS TO LOAD, OR WHOSE OWN `version` DOES NOT MATCH THIS PACKAGE'S
|
|
209
|
+
* VERSION IS A DECLARED REFUSAL AND NEVER A SILENT FALLBACK** (`docs/specs/storeroom-publish/
|
|
210
|
+
* resolution.md §2`, `§5`): **no instance is returned, no JavaScript store is substituted, and the
|
|
211
|
+
* thrown value is the one `StoreRefusal`.** The load path resolves the scoped platform package for this
|
|
212
|
+
* runtime first, this checkout's own module-relative addon second, and answers the declared absent form
|
|
213
|
+
* when neither yields a loadable artefact.
|
|
214
|
+
*/
|
|
215
|
+
export function storeCreate(cfg: StoreConfig): StoreInstance;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Read a leaf's literal, a branch's assembled value, or the empty address's whole register.
|
|
219
|
+
*
|
|
220
|
+
* **`tier` IS THE READER'S ARITY** (`PAR-JS-6`): absent, ONE token, or an ARRAY of tokens read as an
|
|
221
|
+
* ANY-MATCH set — **so the shipped `tier?: Tier` refused, as a type error, a lawful call spelling a set**.
|
|
222
|
+
*/
|
|
223
|
+
export function read(instance: StoreInstance, address: Address, tier?: TierSet): unknown;
|
|
224
|
+
|
|
225
|
+
/** The same read, narrowed to a leaf — a branch answers `ReadTargetIsBranch`; `tier` is `TierSet`. */
|
|
226
|
+
export function readLiteral(instance: StoreInstance, address: Address, tier?: TierSet): unknown;
|
|
227
|
+
|
|
228
|
+
/** Write `value` at `address` on `tier` — EXACTLY ONE token, never an array (`PAR-JS-7`). */
|
|
229
|
+
export function write(instance: StoreInstance, address: Address, tier: Tier, value: unknown): WriteRecord;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Remove the versions the address names, and answer the operation's record.
|
|
233
|
+
*
|
|
234
|
+
* **AND THE NAME IS `delete`, WHICH THIS DECLARATION CANNOT BIND AS AN IDENTIFIER**: `delete` is a RESERVED
|
|
235
|
+
* WORD, so the function is declared as `deleteOp` and EXPORTED under the name the entry publishes —
|
|
236
|
+
* `export { deleteOp as delete }` — exactly as `bindings/js/index.mjs` does on its own side.
|
|
237
|
+
* **`export function delete(…)`, WHICH THE SHIPPED FILE CARRIED, IS NOT A PARSEABLE DECLARATION AT ALL**, so
|
|
238
|
+
* a consumer's compiler read no surface from this file rather than a mis-typed one (`P-PUB-7`; `Q3-4`).
|
|
239
|
+
*/
|
|
240
|
+
declare function deleteOp(instance: StoreInstance, address: Address, tier?: Tier): DeleteRecord;
|
|
241
|
+
export { deleteOp as delete };
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Roll the journal back to `opId`, and answer what the rollback restored.
|
|
245
|
+
*
|
|
246
|
+
* **`opId` IS A NON-EMPTY `string` AND NOT A NUMBER** (`PAR-JS-9`'s own unit: *"the `JournalOp.opId`
|
|
247
|
+
* string"*): the shipped `opId: number` both mis-declared the domain — a number is an OUTSIDE value the
|
|
248
|
+
* store answers `AddressMalformed` for — and made the ordinary call `rollback(i, w.op.opId)`, whose id is
|
|
249
|
+
* the string `write` returned, a type error.
|
|
250
|
+
*/
|
|
251
|
+
export function rollback(instance: StoreInstance, opId: string): RollbackRecord;
|
|
252
|
+
|
|
253
|
+
/** Begin watching an address, and answer the fresh opaque handle it is keyed by. */
|
|
254
|
+
export function listen(instance: StoreInstance, address: Address): Handle;
|
|
255
|
+
|
|
256
|
+
/** Withdraw a watching, and answer `undefined` — a no-op success for every value outside the domain. */
|
|
257
|
+
export function unlisten(instance: StoreInstance, handle: Handle): void;
|