@ternent/concord 0.2.5 → 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 CHANGED
@@ -1,46 +1,129 @@
1
1
  # `@ternent/concord`
2
2
 
3
- Command-driven developer runtime for building non-custodial apps on top of `@ternent/ledger`.
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 { createConcordApp } from "@ternent/concord";
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: [createTodoPlugin()]
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 and refine first todo"
29
- }
65
+ message: "Create first todo",
66
+ },
30
67
  });
31
68
 
32
- const todoState = app.getPluginState("todo");
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 keeps Ledger as the truth engine. Plugins own command ergonomics and projection logic, while commits remain explicit authored history boundaries.
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
- Concord treats committed history as atomic truth. If any committed byte in reachable history is invalid, the document is globally invalid for normal runtime use, even though verification still reports the precise broken commits or entries.
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 with contextual metadata
44
- 4. replay rebuilds app state from that history
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
- Entries carry domain meaning. Signed commits carry chain integrity.
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 it is not auto-commit-first.
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 projection, and runtime composition
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 model
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
- - plugin state is derived from replay
55
- - projection targets are derived from replay
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 projected app state
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
- getPluginState<T = unknown>(pluginId: string): T;
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
- ## 5. State model
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
- plugins: Record<string, unknown>;
146
+ replay: Record<string, unknown>;
108
147
  verification: LedgerVerificationResult | null;
109
148
  };
110
149
  ```
111
150
 
112
151
  Rules:
113
152
 
114
- - `plugins` is replay-derived app state
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 plugin state as authority
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
- ## 6. Plugin model
159
+ ## 7. Replay Plugin Model
121
160
 
122
161
  ```ts
123
- type ConcordPlugin<PState = unknown> = {
162
+ type ConcordReplayPlugin<PState = unknown> = {
124
163
  id: string;
125
- initialState(): PState;
126
- commands?: Record<
127
- string,
128
- (
129
- ctx: ConcordCommandContext,
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: ConcordProjectionContext
137
- ): PState;
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
- - `project()` is a pure replay consumer over the plugin state slice and replay entry
147
- - plugins define domain meaning, not truth mechanics
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
- ## 7. Projection targets
227
+ Failure rules:
150
228
 
151
- Projection targets consume replay output after plugin state is rebuilt for the current entry.
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
- They:
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
- - consume replayed truth
156
- - may materialize query stores
157
- - do not author truth
158
- - do not replace plugin projection
256
+ That distinction is important:
159
257
 
160
- Projection target failures fail the Concord operation. They are not swallowed.
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
- ## 8. Runtime rules
261
+ ## 10. Runtime Rules
163
262
 
164
263
  - Concord defaults to `autoCommit: false`
165
- - `command()` stages entries and rebuilds local projected state from committed plus staged replay
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 app state until explicitly committed or cleared below Concord
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 projected state as trustworthy runtime state.
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
- ## 9. Acceptance criteria
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, CreateConcordAppInput } from "./types.js";
2
- export declare function createConcordApp(input: CreateConcordAppInput): Promise<ConcordApp>;
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,EAUV,qBAAqB,EACtB,MAAM,YAAY,CAAC;AA0GpB,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,UAAU,CAAC,CA+arB"}
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, ConcordIdentityContext, ConcordPlugin, ConcordProjectionContext, ConcordProjectionReplayContext, ConcordProjectionTarget, ConcordReplayAppView, ConcordReplayOptions, ConcordRuntimePolicy, ConcordState, CreateConcordAppInput } from "./types.js";
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,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,8BAA8B,EAC9B,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACtB,MAAM,YAAY,CAAC"}
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
- plugins: Record<string, unknown>;
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: ConcordIdentityContext;
39
- getPluginState<T = unknown>(pluginId: string): T;
40
- };
41
- export type ConcordProjectionContext = {
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 ConcordPlugin<PState = unknown> = {
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(): PState;
47
- commands?: Record<string, (ctx: ConcordCommandContext, input: unknown) => Promise<LedgerAppendInput | LedgerAppendInput[]> | LedgerAppendInput | LedgerAppendInput[]>;
48
- project(state: PState, entry: LedgerReplayEntry, ctx: ConcordProjectionContext): PState;
49
- selectors?: Record<string, (state: PState) => unknown>;
50
- };
51
- export type ConcordReplayAppView = {
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 CreateConcordAppInput = {
67
- identity: ConcordIdentityContext;
68
- storage: LedgerStorageAdapter;
69
- plugins: ConcordPlugin[];
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<unknown>;
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
- getPluginState<T = unknown>(pluginId: string): T;
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":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}