@ternent/concord 0.2.4 → 0.2.6
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 +100 -17
- package/SPEC.md +142 -41
- package/dist/concord/src/app.d.ts +2 -2
- package/dist/concord/src/app.d.ts.map +1 -1
- package/dist/concord/src/index.d.ts +1 -1
- package/dist/concord/src/index.d.ts.map +1 -1
- package/dist/concord/src/types.d.ts +37 -36
- package/dist/concord/src/types.d.ts.map +1 -1
- package/dist/index.js +134 -91
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +9200 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -1,46 +1,129 @@
|
|
|
1
1
|
# `@ternent/concord`
|
|
2
2
|
|
|
3
|
-
Command-driven
|
|
3
|
+
Command-driven replay runtime for building non-custodial applications on top of `@ternent/ledger`.
|
|
4
|
+
|
|
5
|
+
Concord is replay-first:
|
|
6
|
+
|
|
7
|
+
- ledger history is truth
|
|
8
|
+
- replay is the primary abstraction
|
|
9
|
+
- replay plugins are the only replay consumer type
|
|
10
|
+
- state, reactivity, databases, and indexes are all projection
|
|
4
11
|
|
|
5
12
|
```ts
|
|
6
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
createConcordApp,
|
|
15
|
+
type ConcordReplayPlugin,
|
|
16
|
+
} from "@ternent/concord";
|
|
17
|
+
|
|
18
|
+
const todoPlugin: ConcordReplayPlugin<{
|
|
19
|
+
items: Record<string, { id: string; title: string; completed: boolean }>;
|
|
20
|
+
}> = {
|
|
21
|
+
id: "todo",
|
|
22
|
+
initialState() {
|
|
23
|
+
return { items: {} };
|
|
24
|
+
},
|
|
25
|
+
commands: {
|
|
26
|
+
"todo.create-item": async (_ctx, input: { id: string; title: string }) => ({
|
|
27
|
+
kind: "todo.item.created",
|
|
28
|
+
payload: input,
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
applyEntry(entry, ctx) {
|
|
32
|
+
if (entry.kind !== "todo.item.created" || entry.payload.type !== "plain") {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const payload = entry.payload.data as { id: string; title: string };
|
|
37
|
+
ctx.setState((state) => ({
|
|
38
|
+
items: {
|
|
39
|
+
...state.items,
|
|
40
|
+
[payload.id]: {
|
|
41
|
+
id: payload.id,
|
|
42
|
+
title: payload.title,
|
|
43
|
+
completed: false,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
},
|
|
48
|
+
};
|
|
7
49
|
|
|
8
50
|
const app = await createConcordApp({
|
|
9
51
|
identity,
|
|
10
52
|
storage,
|
|
11
|
-
plugins: [
|
|
53
|
+
plugins: [todoPlugin],
|
|
12
54
|
});
|
|
13
55
|
|
|
14
56
|
await app.load();
|
|
15
57
|
|
|
16
58
|
await app.command("todo.create-item", {
|
|
17
59
|
id: crypto.randomUUID(),
|
|
18
|
-
title: "Buy milk"
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
await app.command("todo.rename-item", {
|
|
22
|
-
id: "todo_123",
|
|
23
|
-
title: "Buy oat milk"
|
|
60
|
+
title: "Buy milk",
|
|
24
61
|
});
|
|
25
62
|
|
|
26
63
|
await app.commit({
|
|
27
64
|
metadata: {
|
|
28
|
-
message: "Create
|
|
29
|
-
}
|
|
65
|
+
message: "Create first todo",
|
|
66
|
+
},
|
|
30
67
|
});
|
|
31
68
|
|
|
32
|
-
const todoState = app.
|
|
69
|
+
const todoState = app.getReplayState("todo");
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Identity
|
|
73
|
+
|
|
74
|
+
The app passes a single `SerializedIdentity` into Concord:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const app = await createConcordApp({
|
|
78
|
+
identity,
|
|
79
|
+
storage,
|
|
80
|
+
plugins,
|
|
81
|
+
});
|
|
33
82
|
```
|
|
34
83
|
|
|
35
|
-
Concord
|
|
84
|
+
Concord derives author, signer, and decrypt capability internally. Command handlers receive the same high-level `SerializedIdentity` at `ctx.identity`. Ledger-facing identity adaptation stays private to Concord.
|
|
36
85
|
|
|
37
|
-
|
|
86
|
+
## Replay Plugins
|
|
87
|
+
|
|
88
|
+
Replay plugins are the only replay consumer type.
|
|
89
|
+
|
|
90
|
+
- a replay plugin may keep replay-derived state with `initialState()` and `ctx.setState(...)`
|
|
91
|
+
- a replay plugin may materialize into external systems like Loki, Vue refs, React stores, or IndexedDB
|
|
92
|
+
- commands remain typed entry producers
|
|
93
|
+
|
|
94
|
+
`reset` has a narrow meaning:
|
|
95
|
+
|
|
96
|
+
- `reset` prepares plugin-local replay workspace for a new replay pass
|
|
97
|
+
- `reset` does not imply clearing previously published external surfaces
|
|
98
|
+
- if a plugin needs external atomic swap behavior, that belongs to the plugin and usually happens in `endReplay`
|
|
99
|
+
|
|
100
|
+
Concord only guarantees atomicity at the published Concord state boundary. External projection atomicity is plugin-owned.
|
|
101
|
+
|
|
102
|
+
## Replay And Integrity
|
|
38
103
|
|
|
39
104
|
The core lifecycle is:
|
|
40
105
|
|
|
41
106
|
1. `command(...)` stages one or more entries
|
|
42
107
|
2. local replay reflects committed truth plus staged truth
|
|
43
|
-
3. `commit(...)` groups staged entries into a signed commit
|
|
44
|
-
4. replay rebuilds
|
|
108
|
+
3. `commit(...)` groups staged entries into a signed commit
|
|
109
|
+
4. replay rebuilds published runtime state from that history
|
|
110
|
+
|
|
111
|
+
Concord treats committed history as atomic truth. If any reachable committed byte is invalid, Concord does not present the runtime state as trustworthy.
|
|
112
|
+
|
|
113
|
+
## Partial Replay
|
|
114
|
+
|
|
115
|
+
Concord supports ranged replay options:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
await app.replay({
|
|
119
|
+
fromEntryId: "entry_a",
|
|
120
|
+
toEntryId: "entry_b",
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Two distinctions matter:
|
|
125
|
+
|
|
126
|
+
- replay of any ordered slice is deterministic
|
|
127
|
+
- authoritative full-state reconstruction still requires replay from genesis or a valid checkpoint
|
|
45
128
|
|
|
46
|
-
|
|
129
|
+
That distinction is intentional. Partial replay metadata exists so Concord stays compatible with future timeline scrubbing and replay-slider UX without redesigning the plugin contract.
|
package/SPEC.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
`@ternent/concord` is the developer-facing runtime for building non-custodial applications on top of `@ternent/ledger`.
|
|
6
6
|
|
|
7
|
-
Concord is command-first, but
|
|
7
|
+
Concord is command-first, but replay is the primary abstraction.
|
|
8
8
|
|
|
9
9
|
It exists to make this normal:
|
|
10
10
|
|
|
@@ -34,25 +34,25 @@ await app.commit({
|
|
|
34
34
|
});
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Commands stage domain meaning. Commits author signed history boundaries.
|
|
37
|
+
Commands stage domain meaning. Replay plugins consume ordered replay entries. Commits author signed history boundaries.
|
|
38
38
|
|
|
39
39
|
## 2. Layering
|
|
40
40
|
|
|
41
41
|
- `@ternent/concord-protocol` provides deterministic protocol primitives
|
|
42
42
|
- `@ternent/ledger` owns append-only truth, signed commits, replay, and verification
|
|
43
|
-
- `@ternent/concord` owns command dispatch, plugin
|
|
43
|
+
- `@ternent/concord` owns command dispatch, replay plugin hosting, and runtime composition
|
|
44
44
|
- framework adapters belong above Concord
|
|
45
45
|
|
|
46
46
|
Concord must never reimplement ledger truth mechanics.
|
|
47
47
|
|
|
48
|
-
## 3. Core
|
|
48
|
+
## 3. Core Model
|
|
49
49
|
|
|
50
50
|
### 3.1 Truth vs runtime state
|
|
51
51
|
|
|
52
52
|
- entries are units of meaning
|
|
53
53
|
- signed commits are the primary authored integrity boundary
|
|
54
|
-
-
|
|
55
|
-
-
|
|
54
|
+
- replay-derived state is derived from replay
|
|
55
|
+
- replay plugins are the only replay consumer type
|
|
56
56
|
- storage is persistence only
|
|
57
57
|
|
|
58
58
|
### 3.2 Command and commit lifecycle
|
|
@@ -61,7 +61,7 @@ The normal Concord write lifecycle is:
|
|
|
61
61
|
|
|
62
62
|
1. dispatch one or more commands
|
|
63
63
|
2. stage one or more ledger entries
|
|
64
|
-
3. replay committed truth plus staged truth into
|
|
64
|
+
3. replay committed truth plus staged truth into replay-derived runtime state
|
|
65
65
|
4. explicitly commit staged entries into a signed commit
|
|
66
66
|
5. replay the updated committed history
|
|
67
67
|
|
|
@@ -90,86 +90,185 @@ type ConcordApp = {
|
|
|
90
90
|
importLedger(container: LedgerContainer): Promise<void>;
|
|
91
91
|
|
|
92
92
|
getState(): Readonly<ConcordState>;
|
|
93
|
-
|
|
93
|
+
getReplayState<T = unknown>(pluginId: string): T;
|
|
94
94
|
|
|
95
95
|
subscribe(listener: (state: Readonly<ConcordState>) => void): () => void;
|
|
96
96
|
destroy(): Promise<void>;
|
|
97
97
|
};
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
`ConcordAppOptions` uses:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
type ConcordAppOptions = {
|
|
104
|
+
identity: SerializedIdentity;
|
|
105
|
+
storage?: LedgerStorageAdapter;
|
|
106
|
+
plugins: ConcordReplayPlugin[];
|
|
107
|
+
now?: () => string;
|
|
108
|
+
protocol?: LedgerProtocolContract;
|
|
109
|
+
seal?: LedgerSealContract;
|
|
110
|
+
armour?: LedgerArmourContract;
|
|
111
|
+
ledger?: LedgerInstance<LedgerReplayEntry[]>;
|
|
112
|
+
policy?: ConcordRuntimePolicy;
|
|
113
|
+
};
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Rules:
|
|
117
|
+
|
|
118
|
+
- `storage` is optional
|
|
119
|
+
- a supplied ledger must replay `LedgerReplayEntry[]`
|
|
120
|
+
- the app passes one high-level identity object
|
|
121
|
+
- Concord derives author, signer, and decrypt capability internally when it creates the ledger
|
|
122
|
+
|
|
123
|
+
## 5. Identity Model
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
type SerializedIdentity = {
|
|
127
|
+
keyId: string;
|
|
128
|
+
// ...
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Rules:
|
|
133
|
+
|
|
134
|
+
- this is the public identity shape the app passes to Concord
|
|
135
|
+
- Concord internally adapts it into ledger signer / author / decryptor wiring
|
|
136
|
+
- command handlers receive this same high-level identity unchanged
|
|
137
|
+
- replay plugins do not receive ledger adaptation details
|
|
138
|
+
|
|
139
|
+
## 6. State Model
|
|
101
140
|
|
|
102
141
|
```ts
|
|
103
142
|
type ConcordState = {
|
|
104
143
|
ready: boolean;
|
|
105
144
|
integrityValid: boolean;
|
|
106
145
|
stagedCount: number;
|
|
107
|
-
|
|
146
|
+
replay: Record<string, unknown>;
|
|
108
147
|
verification: LedgerVerificationResult | null;
|
|
109
148
|
};
|
|
110
149
|
```
|
|
111
150
|
|
|
112
151
|
Rules:
|
|
113
152
|
|
|
114
|
-
- `
|
|
153
|
+
- `replay` is replay-derived runtime state
|
|
115
154
|
- `integrityValid` indicates whether the currently loaded committed history passed strict ledger verification
|
|
116
155
|
- `stagedCount` exposes local working-state depth without leaking raw ledger internals as the primary surface
|
|
117
|
-
- verification applies to the ledger artifact and current staged state, not to
|
|
156
|
+
- verification applies to the ledger artifact and current staged state, not to replay-derived state as authority
|
|
118
157
|
- `ready` means the app has a trustworthy projected runtime state available for normal use
|
|
119
158
|
|
|
120
|
-
##
|
|
159
|
+
## 7. Replay Plugin Model
|
|
121
160
|
|
|
122
161
|
```ts
|
|
123
|
-
type
|
|
162
|
+
type ConcordReplayPlugin<PState = unknown> = {
|
|
124
163
|
id: string;
|
|
125
|
-
initialState()
|
|
126
|
-
commands?: Record<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
input: unknown
|
|
131
|
-
) => Promise<LedgerAppendInput | LedgerAppendInput[]> | LedgerAppendInput | LedgerAppendInput[]
|
|
132
|
-
>;
|
|
133
|
-
project(
|
|
134
|
-
state: PState,
|
|
164
|
+
initialState?: () => PState;
|
|
165
|
+
commands?: Record<string, ConcordCommandHandler>;
|
|
166
|
+
reset?: (ctx: ConcordReplayContext<PState>) => Promise<void> | void;
|
|
167
|
+
beginReplay?: (ctx: ConcordReplayContext<PState>) => Promise<void> | void;
|
|
168
|
+
applyEntry?: (
|
|
135
169
|
entry: LedgerReplayEntry,
|
|
136
|
-
ctx:
|
|
137
|
-
)
|
|
170
|
+
ctx: ConcordReplayContext<PState>
|
|
171
|
+
) => Promise<void> | void;
|
|
172
|
+
endReplay?: (ctx: ConcordReplayContext<PState>) => Promise<void> | void;
|
|
173
|
+
destroy?: () => Promise<void> | void;
|
|
138
174
|
selectors?: Record<string, (state: PState) => unknown>;
|
|
139
175
|
};
|
|
140
176
|
```
|
|
141
177
|
|
|
178
|
+
Replay context:
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
type ConcordReplayContext<PState = unknown> = {
|
|
182
|
+
pluginId: string;
|
|
183
|
+
decryptAvailable: boolean;
|
|
184
|
+
replay: {
|
|
185
|
+
phase: "reset" | "beginReplay" | "applyEntry" | "endReplay";
|
|
186
|
+
entryIndex?: number;
|
|
187
|
+
entryCount: number;
|
|
188
|
+
fromEntryId?: string;
|
|
189
|
+
toEntryId?: string;
|
|
190
|
+
isPartial: boolean;
|
|
191
|
+
};
|
|
192
|
+
getState(): PState;
|
|
193
|
+
setState(next: PState | ((prev: PState) => PState)): void;
|
|
194
|
+
};
|
|
195
|
+
```
|
|
196
|
+
|
|
142
197
|
Rules:
|
|
143
198
|
|
|
199
|
+
- replay plugins are the only replay consumer type
|
|
144
200
|
- commands return ledger append inputs
|
|
145
201
|
- commands stage entries; they do not implicitly define commit boundaries
|
|
146
|
-
-
|
|
147
|
-
- plugins
|
|
202
|
+
- replay plugins are isolated by plugin id
|
|
203
|
+
- replay plugins can read and write only their own replay state during replay
|
|
204
|
+
- Concord does not support cross-plugin replay reads during a replay pass
|
|
205
|
+
|
|
206
|
+
`reset` has strict semantics:
|
|
207
|
+
|
|
208
|
+
- `reset` prepares plugin-local replay workspace for a new replay pass
|
|
209
|
+
- `reset` does not imply clearing previously published external surfaces
|
|
210
|
+
- external atomic swap, if needed, belongs to the plugin and usually happens in `endReplay`
|
|
211
|
+
|
|
212
|
+
`selectors` are passive metadata only. Concord does not add selector runtime behavior.
|
|
213
|
+
|
|
214
|
+
## 8. Replay Rules
|
|
215
|
+
|
|
216
|
+
Concord rebuilds runtime state with one replay pipeline:
|
|
217
|
+
|
|
218
|
+
1. verify committed history before trusted rebuild
|
|
219
|
+
2. ask Ledger for ordered replay entries
|
|
220
|
+
3. create isolated draft replay state for all plugins
|
|
221
|
+
4. run `reset`
|
|
222
|
+
5. run `beginReplay`
|
|
223
|
+
6. run `applyEntry` for each ordered entry
|
|
224
|
+
7. run `endReplay`
|
|
225
|
+
8. publish Concord state once after full success
|
|
148
226
|
|
|
149
|
-
|
|
227
|
+
Failure rules:
|
|
150
228
|
|
|
151
|
-
|
|
229
|
+
- abort immediately on any replay hook failure
|
|
230
|
+
- do not publish partial Concord state
|
|
231
|
+
- do not mutate the last-known-good published Concord state
|
|
232
|
+
- do not attempt cleanup `reset` or rollback magic
|
|
233
|
+
|
|
234
|
+
Atomicity rule:
|
|
235
|
+
|
|
236
|
+
- Concord guarantees atomicity only at the published Concord state boundary
|
|
237
|
+
- external surfaces owned by plugins must handle their own buffered publish / swap if they need atomic updates
|
|
238
|
+
|
|
239
|
+
## 9. Partial Replay
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
type ConcordReplayOptions = {
|
|
243
|
+
verify?: boolean;
|
|
244
|
+
decrypt?: boolean;
|
|
245
|
+
fromEntryId?: string;
|
|
246
|
+
toEntryId?: string;
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Rules:
|
|
152
251
|
|
|
153
|
-
|
|
252
|
+
- replay of any ordered slice is deterministic
|
|
253
|
+
- replay metadata is range-aware so Concord stays compatible with timeline scrubbing and replay-slider UX
|
|
254
|
+
- authoritative full-state reconstruction still requires replay from genesis or a valid checkpoint
|
|
154
255
|
|
|
155
|
-
|
|
156
|
-
- may materialize query stores
|
|
157
|
-
- do not author truth
|
|
158
|
-
- do not replace plugin projection
|
|
256
|
+
That distinction is important:
|
|
159
257
|
|
|
160
|
-
|
|
258
|
+
- deterministic slice replay is supported now
|
|
259
|
+
- authoritative full-state reconstruction from a non-zero start requires a valid checkpoint layer that Concord does not yet provide
|
|
161
260
|
|
|
162
|
-
##
|
|
261
|
+
## 10. Runtime Rules
|
|
163
262
|
|
|
164
263
|
- Concord defaults to `autoCommit: false`
|
|
165
|
-
- `command()` stages entries and rebuilds local
|
|
264
|
+
- `command()` stages entries and rebuilds local replay-derived state from committed plus staged replay
|
|
166
265
|
- `commit()` creates a signed commit via Ledger and clears staged entries only after successful commit creation
|
|
167
266
|
- `verify()` validates the ledger artifact and current staged state; it does not itself replay
|
|
168
267
|
- `exportLedger()` exposes committed truth only
|
|
169
|
-
- staged truth remains visible through replayed
|
|
268
|
+
- staged truth remains visible through replayed runtime state until explicitly committed or cleared below Concord
|
|
170
269
|
|
|
171
270
|
Concord treats committed history as atomic truth.
|
|
172
|
-
If any committed byte in reachable history is invalid, Concord must not present
|
|
271
|
+
If any committed byte in reachable history is invalid, Concord must not present replay-derived runtime state as trustworthy.
|
|
173
272
|
|
|
174
273
|
That means:
|
|
175
274
|
|
|
@@ -178,7 +277,7 @@ That means:
|
|
|
178
277
|
- invalid committed history forces `integrityValid: false`
|
|
179
278
|
- commands and commits are blocked until trustworthy runtime state exists again
|
|
180
279
|
|
|
181
|
-
##
|
|
280
|
+
## 11. Acceptance Criteria
|
|
182
281
|
|
|
183
282
|
Concord is correct when:
|
|
184
283
|
|
|
@@ -186,4 +285,6 @@ Concord is correct when:
|
|
|
186
285
|
- staged state is visible through replay before commit
|
|
187
286
|
- committed history is advanced only by explicit commit unless auto-commit is intentionally configured
|
|
188
287
|
- exported ledgers show signed commit records as the authored integrity boundary
|
|
288
|
+
- replay plugins are the only replay consumer type
|
|
189
289
|
- docs and examples teach `command -> command -> commit`, not `command = commit`
|
|
290
|
+
- docs clearly distinguish deterministic slice replay from authoritative full-state reconstruction
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ConcordApp,
|
|
2
|
-
export declare function createConcordApp(input:
|
|
1
|
+
import type { ConcordApp, ConcordAppOptions } from "./types.js";
|
|
2
|
+
export declare function createConcordApp(input: ConcordAppOptions): Promise<ConcordApp>;
|
|
3
3
|
//# sourceMappingURL=app.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EAWlB,MAAM,YAAY,CAAC;AA2KpB,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,UAAU,CAAC,CAqbrB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createConcordApp } from "./app.js";
|
|
2
2
|
export { ConcordBoundaryError } from "./errors.js";
|
|
3
|
-
export type { ConcordApp, ConcordCommandContext, ConcordCommitInput, ConcordCommitResult, ConcordCommandResult, ConcordCreateParams,
|
|
3
|
+
export type { ConcordApp, ConcordAppOptions, ConcordCommandContext, ConcordCommandHandler, ConcordCommitInput, ConcordCommitResult, ConcordCommandResult, ConcordCreateParams, ConcordReplayContext, ConcordReplayMetadata, ConcordReplayOptions, ConcordReplayPhase, ConcordReplayPlugin, ConcordRuntimePolicy, ConcordState, CreateConcordAppInput, } from "./types.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import type { LedgerAppendInput, LedgerArmourContract, LedgerContainer, LedgerInstance, LedgerProtocolContract, LedgerReplayEntry, LedgerSealContract, LedgerStorageAdapter, LedgerVerificationResult } from "@ternent/ledger";
|
|
2
|
+
import type { SerializedIdentity } from "@ternent/identity";
|
|
2
3
|
export type ConcordCreateParams = {
|
|
3
4
|
metadata?: Record<string, unknown>;
|
|
4
5
|
};
|
|
5
6
|
export type ConcordReplayOptions = {
|
|
6
7
|
verify?: boolean;
|
|
7
8
|
decrypt?: boolean;
|
|
9
|
+
fromEntryId?: string;
|
|
10
|
+
toEntryId?: string;
|
|
8
11
|
};
|
|
9
12
|
export type ConcordState = {
|
|
10
13
|
ready: boolean;
|
|
11
14
|
integrityValid: boolean;
|
|
12
15
|
stagedCount: number;
|
|
13
|
-
|
|
16
|
+
replay: Record<string, unknown>;
|
|
14
17
|
verification: LedgerVerificationResult | null;
|
|
15
18
|
};
|
|
16
19
|
export type ConcordCommandResult = {
|
|
@@ -28,53 +31,51 @@ export type ConcordCommitResult = {
|
|
|
28
31
|
export type ConcordRuntimePolicy = {
|
|
29
32
|
autoCommit?: boolean;
|
|
30
33
|
};
|
|
31
|
-
export type ConcordIdentityContext = {
|
|
32
|
-
author: string;
|
|
33
|
-
signer?: unknown;
|
|
34
|
-
decryptor?: unknown;
|
|
35
|
-
};
|
|
36
34
|
export type ConcordCommandContext = {
|
|
37
35
|
now(): string;
|
|
38
|
-
identity:
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
export type
|
|
36
|
+
identity: SerializedIdentity;
|
|
37
|
+
getReplayState<T = unknown>(pluginId: string): T;
|
|
38
|
+
};
|
|
39
|
+
export type ConcordReplayPhase = "reset" | "beginReplay" | "applyEntry" | "endReplay";
|
|
40
|
+
export type ConcordReplayMetadata = {
|
|
41
|
+
phase: ConcordReplayPhase;
|
|
42
|
+
entryIndex?: number;
|
|
43
|
+
entryCount: number;
|
|
44
|
+
fromEntryId?: string;
|
|
45
|
+
toEntryId?: string;
|
|
46
|
+
isPartial: boolean;
|
|
47
|
+
};
|
|
48
|
+
export type ConcordReplayContext<TState = unknown> = {
|
|
49
|
+
pluginId: string;
|
|
42
50
|
decryptAvailable: boolean;
|
|
51
|
+
replay: ConcordReplayMetadata;
|
|
52
|
+
getState(): TState;
|
|
53
|
+
setState(next: TState | ((prev: TState) => TState)): void;
|
|
43
54
|
};
|
|
44
|
-
export type
|
|
55
|
+
export type ConcordCommandHandler = (ctx: ConcordCommandContext, input: unknown) => Promise<LedgerAppendInput | LedgerAppendInput[]> | LedgerAppendInput | LedgerAppendInput[];
|
|
56
|
+
export type ConcordReplayPlugin<TState = unknown> = {
|
|
45
57
|
id: string;
|
|
46
|
-
initialState()
|
|
47
|
-
commands?: Record<string,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
getState(): Readonly<ConcordState>;
|
|
53
|
-
getPluginState<T = unknown>(pluginId: string): T;
|
|
54
|
-
};
|
|
55
|
-
export type ConcordProjectionReplayContext = {
|
|
56
|
-
app: ConcordReplayAppView;
|
|
57
|
-
};
|
|
58
|
-
export type ConcordProjectionTarget = {
|
|
59
|
-
name: string;
|
|
60
|
-
reset(): Promise<void> | void;
|
|
61
|
-
beginReplay?(ctx: ConcordProjectionReplayContext): Promise<void> | void;
|
|
62
|
-
applyEntry(entry: LedgerReplayEntry, ctx: ConcordProjectionReplayContext): Promise<void> | void;
|
|
63
|
-
endReplay?(ctx: ConcordProjectionReplayContext): Promise<void> | void;
|
|
58
|
+
initialState?: () => TState;
|
|
59
|
+
commands?: Record<string, ConcordCommandHandler>;
|
|
60
|
+
reset?: (ctx: ConcordReplayContext<TState>) => Promise<void> | void;
|
|
61
|
+
beginReplay?: (ctx: ConcordReplayContext<TState>) => Promise<void> | void;
|
|
62
|
+
applyEntry?: (entry: LedgerReplayEntry, ctx: ConcordReplayContext<TState>) => Promise<void> | void;
|
|
63
|
+
endReplay?: (ctx: ConcordReplayContext<TState>) => Promise<void> | void;
|
|
64
64
|
destroy?(): Promise<void> | void;
|
|
65
|
+
selectors?: Record<string, (state: TState) => unknown>;
|
|
65
66
|
};
|
|
66
|
-
export type
|
|
67
|
-
identity:
|
|
68
|
-
storage
|
|
69
|
-
plugins:
|
|
67
|
+
export type ConcordAppOptions = {
|
|
68
|
+
identity: SerializedIdentity;
|
|
69
|
+
storage?: LedgerStorageAdapter;
|
|
70
|
+
plugins: ConcordReplayPlugin[];
|
|
70
71
|
now?: () => string;
|
|
71
72
|
protocol?: LedgerProtocolContract;
|
|
72
73
|
seal?: LedgerSealContract;
|
|
73
74
|
armour?: LedgerArmourContract;
|
|
74
|
-
ledger?: LedgerInstance<
|
|
75
|
-
projectionTargets?: ConcordProjectionTarget[];
|
|
75
|
+
ledger?: LedgerInstance<LedgerReplayEntry[]>;
|
|
76
76
|
policy?: ConcordRuntimePolicy;
|
|
77
77
|
};
|
|
78
|
+
export type CreateConcordAppInput = ConcordAppOptions;
|
|
78
79
|
export type ConcordApp = {
|
|
79
80
|
create(params?: ConcordCreateParams): Promise<void>;
|
|
80
81
|
load(): Promise<void>;
|
|
@@ -86,7 +87,7 @@ export type ConcordApp = {
|
|
|
86
87
|
exportLedger(): Promise<LedgerContainer>;
|
|
87
88
|
importLedger(container: LedgerContainer): Promise<void>;
|
|
88
89
|
getState(): Readonly<ConcordState>;
|
|
89
|
-
|
|
90
|
+
getReplayState<T = unknown>(pluginId: string): T;
|
|
90
91
|
subscribe(listener: (state: Readonly<ConcordState>) => void): () => void;
|
|
91
92
|
destroy(): Promise<void>;
|
|
92
93
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}
|