@ifc-lite/flow-nodes 0.6.0 → 0.9.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.
Files changed (112) hide show
  1. package/README.md +118 -0
  2. package/dist/ai-classify.d.ts +8 -0
  3. package/dist/ai-classify.d.ts.map +1 -0
  4. package/dist/ai-classify.js +113 -0
  5. package/dist/ai-classify.js.map +1 -0
  6. package/dist/ai-extract.d.ts +26 -0
  7. package/dist/ai-extract.d.ts.map +1 -0
  8. package/dist/ai-extract.js +127 -0
  9. package/dist/ai-extract.js.map +1 -0
  10. package/dist/ai-propose-fields.d.ts +12 -0
  11. package/dist/ai-propose-fields.d.ts.map +1 -0
  12. package/dist/ai-propose-fields.js +57 -0
  13. package/dist/ai-propose-fields.js.map +1 -0
  14. package/dist/ai-propose.d.ts +3 -0
  15. package/dist/ai-propose.d.ts.map +1 -0
  16. package/dist/ai-propose.js +94 -0
  17. package/dist/ai-propose.js.map +1 -0
  18. package/dist/ai-response-schemas.d.ts +11 -0
  19. package/dist/ai-response-schemas.d.ts.map +1 -0
  20. package/dist/ai-response-schemas.js +46 -0
  21. package/dist/ai-response-schemas.js.map +1 -0
  22. package/dist/ai-service.d.ts +60 -0
  23. package/dist/ai-service.d.ts.map +1 -0
  24. package/dist/ai-service.js +109 -0
  25. package/dist/ai-service.js.map +1 -0
  26. package/dist/ai-summarize.d.ts +3 -0
  27. package/dist/ai-summarize.d.ts.map +1 -0
  28. package/dist/ai-summarize.js +75 -0
  29. package/dist/ai-summarize.js.map +1 -0
  30. package/dist/ai.d.ts +15 -0
  31. package/dist/ai.d.ts.map +1 -0
  32. package/dist/ai.js +10 -0
  33. package/dist/ai.js.map +1 -0
  34. package/dist/bcf-nodes.d.ts.map +1 -1
  35. package/dist/bcf-nodes.js +12 -2
  36. package/dist/bcf-nodes.js.map +1 -1
  37. package/dist/bcf-publication-capacity.d.ts +5 -0
  38. package/dist/bcf-publication-capacity.d.ts.map +1 -0
  39. package/dist/bcf-publication-capacity.js +44 -0
  40. package/dist/bcf-publication-capacity.js.map +1 -0
  41. package/dist/bcf-publication-check.d.ts +4 -0
  42. package/dist/bcf-publication-check.d.ts.map +1 -0
  43. package/dist/bcf-publication-check.js +100 -0
  44. package/dist/bcf-publication-check.js.map +1 -0
  45. package/dist/bcf-publication-codec.d.ts +53 -0
  46. package/dist/bcf-publication-codec.d.ts.map +1 -0
  47. package/dist/bcf-publication-codec.js +247 -0
  48. package/dist/bcf-publication-codec.js.map +1 -0
  49. package/dist/bcf-publication-epochs.d.ts +17 -0
  50. package/dist/bcf-publication-epochs.d.ts.map +1 -0
  51. package/dist/bcf-publication-epochs.js +104 -0
  52. package/dist/bcf-publication-epochs.js.map +1 -0
  53. package/dist/bcf-publication-history.d.ts +8 -0
  54. package/dist/bcf-publication-history.d.ts.map +1 -0
  55. package/dist/bcf-publication-history.js +84 -0
  56. package/dist/bcf-publication-history.js.map +1 -0
  57. package/dist/bcf-publication-node.d.ts +4 -0
  58. package/dist/bcf-publication-node.d.ts.map +1 -0
  59. package/dist/bcf-publication-node.js +235 -0
  60. package/dist/bcf-publication-node.js.map +1 -0
  61. package/dist/bcf-publication-owner.d.ts +7 -0
  62. package/dist/bcf-publication-owner.d.ts.map +1 -0
  63. package/dist/bcf-publication-owner.js +94 -0
  64. package/dist/bcf-publication-owner.js.map +1 -0
  65. package/dist/bcf-publication-store.d.ts +40 -0
  66. package/dist/bcf-publication-store.d.ts.map +1 -0
  67. package/dist/bcf-publication-store.js +312 -0
  68. package/dist/bcf-publication-store.js.map +1 -0
  69. package/dist/bcf-publication-types.d.ts +105 -0
  70. package/dist/bcf-publication-types.d.ts.map +1 -0
  71. package/dist/bcf-publication-types.js +5 -0
  72. package/dist/bcf-publication-types.js.map +1 -0
  73. package/dist/bcf-publication.d.ts +13 -0
  74. package/dist/bcf-publication.d.ts.map +1 -0
  75. package/dist/bcf-publication.js +24 -0
  76. package/dist/bcf-publication.js.map +1 -0
  77. package/dist/bcf-write-gateway.d.ts +41 -0
  78. package/dist/bcf-write-gateway.d.ts.map +1 -0
  79. package/dist/bcf-write-gateway.js +75 -0
  80. package/dist/bcf-write-gateway.js.map +1 -0
  81. package/dist/capability.d.ts +4 -0
  82. package/dist/capability.d.ts.map +1 -0
  83. package/dist/capability.js +21 -0
  84. package/dist/capability.js.map +1 -0
  85. package/dist/element-nodes.d.ts +9 -1
  86. package/dist/element-nodes.d.ts.map +1 -1
  87. package/dist/element-nodes.js +82 -9
  88. package/dist/element-nodes.js.map +1 -1
  89. package/dist/host.d.ts +41 -40
  90. package/dist/host.d.ts.map +1 -1
  91. package/dist/host.js +2 -31
  92. package/dist/host.js.map +1 -1
  93. package/dist/ids-nodes.d.ts +23 -0
  94. package/dist/ids-nodes.d.ts.map +1 -0
  95. package/dist/ids-nodes.js +180 -0
  96. package/dist/ids-nodes.js.map +1 -0
  97. package/dist/index.d.ts +1 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +4 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/ports.d.ts +38 -0
  102. package/dist/ports.d.ts.map +1 -0
  103. package/dist/ports.js +14 -0
  104. package/dist/ports.js.map +1 -0
  105. package/dist/review-node.d.ts +3 -0
  106. package/dist/review-node.d.ts.map +1 -0
  107. package/dist/review-node.js +20 -0
  108. package/dist/review-node.js.map +1 -0
  109. package/dist/speckle/url.d.ts.map +1 -1
  110. package/dist/speckle/url.js +9 -1
  111. package/dist/speckle/url.js.map +1 -1
  112. package/package.json +32 -12
@@ -0,0 +1,40 @@
1
+ import type { NativeBcfOwnerStatus, NativeBcfPublicationEntry, NativeBcfPublicationPageOptions, StoredBcfAttempt, StoredBcfCheck, StoredBcfOutcome } from './bcf-publication-types.js';
2
+ export interface LoadedAttempt {
3
+ attempt: StoredBcfAttempt;
4
+ outcome?: StoredBcfOutcome;
5
+ checks: StoredBcfCheck[];
6
+ reconciled?: StoredBcfOutcome;
7
+ ownerStatus: NativeBcfOwnerStatus;
8
+ ownerConfirmed?: boolean;
9
+ checkPending?: boolean;
10
+ }
11
+ export declare function entryOf(item: LoadedAttempt, sendFinished?: boolean): NativeBcfPublicationEntry;
12
+ /** Immutable fsynced v2 records. No receipt, capacity slot or predecessor is ever deleted. */
13
+ export declare class BcfPublicationStore {
14
+ readonly directory: string;
15
+ constructor(directory: string);
16
+ private bucket;
17
+ private path;
18
+ prepare(): Promise<void>;
19
+ private syncDirectory;
20
+ private publishAt;
21
+ publish(filename: string, value: unknown, secrets?: readonly string[], onLinked?: () => void): Promise<void>;
22
+ private readAt;
23
+ private epochPath;
24
+ private epochRead;
25
+ private checks;
26
+ ensureEpoch(attempt: StoredBcfAttempt, previous?: StoredBcfCheck, secrets?: readonly string[]): Promise<void>;
27
+ private names;
28
+ load(digest: string, targetId?: string, secrets?: readonly string[]): Promise<LoadedAttempt[]>;
29
+ /** Acknowledgment follows one fsync AFTER all verified root reads; no receipt escapes before it. */
30
+ private history;
31
+ /** Weakly consistent pages: a cursor progresses at the work/byte bound, even without rows. */
32
+ page(options?: NativeBcfPublicationPageOptions, secrets?: readonly string[]): Promise<{
33
+ entries: NativeBcfPublicationEntry[];
34
+ nextCursor: string;
35
+ } | {
36
+ entries: NativeBcfPublicationEntry[];
37
+ nextCursor?: undefined;
38
+ }>;
39
+ }
40
+ //# sourceMappingURL=bcf-publication-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-store.d.ts","sourceRoot":"","sources":["../src/bcf-publication-store.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,+BAA+B,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEvL,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,WAAW,EAAE,oBAAoB,CAAC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,YAAY,UAAQ,GAAG,yBAAyB,CAO5F;AAED,8FAA8F;AAC9F,qBAAa,mBAAmB;IAClB,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;IACtC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACN,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBhB,aAAa;YAIb,SAAS;IAoBjB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAoBxG,MAAM;IAcpB,OAAO,CAAC,SAAS;YACH,SAAS;IASvB,OAAO,CAAC,MAAM;IAMR,WAAW,CAAC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,cAAc,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAgBzG,KAAK;IAoBb,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAMxG,oGAAoG;YACtF,OAAO;IAQrB,8FAA8F;IACxF,IAAI,CAAC,OAAO,GAAE,+BAAoC,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO;;;;;;;CAwD1F"}
@@ -0,0 +1,312 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { Buffer } from 'node:buffer';
5
+ import { constants } from 'node:fs';
6
+ import { link, lstat, mkdir, open, opendir, unlink } from 'node:fs/promises';
7
+ import { dirname, join } from 'node:path';
8
+ import { randomUUID } from 'node:crypto';
9
+ import { credentialFree, MAX_GENERATIONS, MAX_RECORD_BYTES, MAX_RECORDS, NATIVE_METADATA, record, refuse } from './bcf-publication-codec.js';
10
+ import { epochOf, loadCheckEpoch, verifyCheckEpoch } from './bcf-publication-epochs.js';
11
+ import { loadBcfHistory } from './bcf-publication-history.js';
12
+ import { capacityDigest, DIGEST_SLOTS, reserveDigest } from './bcf-publication-capacity.js';
13
+ const errorCode = (error) => record(error) ? error.code : undefined;
14
+ export function entryOf(item, sendFinished = false) {
15
+ const outcome = item.reconciled ?? item.outcome;
16
+ const check = item.checks.at(-1)?.check;
17
+ return { id: item.attempt.id, intent: item.attempt.intent, queuedAt: item.attempt.queuedAt,
18
+ state: outcome?.state ?? (item.ownerStatus === 'alive' && !sendFinished ? NATIVE_METADATA.state.sending : NATIVE_METADATA.state.uncertain),
19
+ ...(outcome?.receipt ? { receipt: outcome.receipt } : {}), ...(outcome?.failure ? { failure: outcome.failure } : {}),
20
+ ...(check ? { check } : {}), ...(!outcome ? { ownerStatus: item.ownerStatus } : {}) };
21
+ }
22
+ /** Immutable fsynced v2 records. No receipt, capacity slot or predecessor is ever deleted. */
23
+ export class BcfPublicationStore {
24
+ directory;
25
+ constructor(directory) {
26
+ this.directory = directory;
27
+ }
28
+ bucket(prefix) { return join(this.directory, 'v2', prefix); }
29
+ path(digest) { return join(this.bucket(digest.slice(0, 2)), digest); }
30
+ async prepare() {
31
+ const ancestors = [];
32
+ for (let path = this.directory;; path = dirname(path)) {
33
+ if (ancestors.length >= 128)
34
+ refuse('configured outbox exceeds directory depth bound');
35
+ ancestors.push(path);
36
+ if (dirname(path) === path)
37
+ break;
38
+ }
39
+ const firstCreated = await mkdir(this.directory, { recursive: true, mode: 0o700 });
40
+ if (!(await lstat(this.directory)).isDirectory())
41
+ refuse('invalid namespace directory');
42
+ const entries = await opendir(this.directory);
43
+ for await (const item of entries) {
44
+ if (item.name !== 'v2' || !item.isDirectory()) {
45
+ refuse('old flat publication layout: preserve this outbox; recover with its original build before selecting a new empty outbox');
46
+ }
47
+ }
48
+ await mkdir(join(this.directory, 'v2'), { recursive: true, mode: 0o700 });
49
+ await this.syncDirectory(join(this.directory, 'v2'));
50
+ // Existing ancestors may have just been created by a different first-use writer.
51
+ // Persist every parent entry before effects, not only the mkdir winner's subtree.
52
+ if (firstCreated !== undefined && !ancestors.includes(firstCreated))
53
+ refuse('created namespace ancestor identity mismatch');
54
+ for (const path of ancestors) {
55
+ if (!(await lstat(path)).isDirectory())
56
+ refuse('invalid publication ancestor');
57
+ await this.syncDirectory(path);
58
+ }
59
+ }
60
+ async syncDirectory(directory) {
61
+ const handle = await open(directory, constants.O_RDONLY | constants.O_DIRECTORY);
62
+ try {
63
+ await handle.sync();
64
+ }
65
+ finally {
66
+ await handle.close();
67
+ }
68
+ }
69
+ async publishAt(directory, filename, value, prefix, onLinked) {
70
+ const bytes = JSON.stringify(value);
71
+ if (Buffer.byteLength(bytes) > MAX_RECORD_BYTES)
72
+ refuse('record exceeds storage bound');
73
+ credentialFree(value, []);
74
+ // Temporary debris stays outside the bounded per-digest recovery history.
75
+ // Same-filesystem hardlink publication remains exclusive; no active temporary is deleted by recovery.
76
+ if (!/^[a-f0-9]{2}$/.test(prefix))
77
+ refuse('invalid temporary bucket prefix');
78
+ const temporary = join(this.bucket(prefix), `.tmp-${randomUUID()}`);
79
+ const handle = await open(temporary, 'wx', 0o600);
80
+ try {
81
+ await handle.writeFile(bytes);
82
+ await handle.sync();
83
+ }
84
+ finally {
85
+ await handle.close();
86
+ }
87
+ try {
88
+ await link(temporary, join(directory, filename));
89
+ onLinked?.();
90
+ await this.syncDirectory(directory);
91
+ }
92
+ finally {
93
+ try {
94
+ await unlink(temporary);
95
+ }
96
+ catch (error) {
97
+ if (errorCode(error) !== 'ENOENT')
98
+ console.warn('[BCF publication] Could not remove temporary intent file', error);
99
+ }
100
+ }
101
+ }
102
+ async publish(filename, value, secrets = [], onLinked) {
103
+ credentialFree(value, secrets);
104
+ if (!/^[a-f0-9]{64}-[1-9][0-9]*\.(?:intent|outcome|owner-stopped|(?:check|checked)-[1-9][0-9]{0,15})\.json$/.test(filename))
105
+ refuse('invalid publication filename');
106
+ const digest = filename.slice(0, 64);
107
+ const bucket = this.bucket(digest.slice(0, 2));
108
+ await mkdir(bucket, { recursive: true, mode: 0o700 });
109
+ if (!(await lstat(bucket)).isDirectory())
110
+ refuse('invalid digest bucket');
111
+ await this.syncDirectory(join(this.directory, 'v2'));
112
+ await reserveDigest(bucket, digest, (directory, file, value) => {
113
+ credentialFree(value, secrets);
114
+ return this.publishAt(directory, file, value, digest.slice(0, 2));
115
+ }, (directory, file) => this.readAt(directory, file, false), this.syncDirectory.bind(this));
116
+ const path = this.path(digest);
117
+ await mkdir(path, { recursive: true, mode: 0o700 });
118
+ if (!(await lstat(path)).isDirectory())
119
+ refuse('invalid publication directory');
120
+ await this.syncDirectory(bucket);
121
+ const check = /\.(?:check|checked)-([1-9][0-9]*)\.json$/.exec(filename);
122
+ await this.publishAt(check ? this.epochPath(filename.slice(0, filename.indexOf('.')), epochOf(check[1])) : path, filename, value, digest.slice(0, 2), filename.endsWith('.intent.json') ? onLinked : undefined);
123
+ }
124
+ async readAt(directory, filename, syncEntry = true) {
125
+ const handle = await open(join(directory, filename), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
126
+ try {
127
+ const stat = await handle.stat();
128
+ if (!stat.isFile() || stat.size > MAX_RECORD_BYTES)
129
+ refuse('invalid or oversized stored record');
130
+ const bytes = Buffer.alloc(MAX_RECORD_BYTES + 1);
131
+ const result = await handle.read(bytes, 0, bytes.length, 0);
132
+ if (result.bytesRead > MAX_RECORD_BYTES)
133
+ refuse('record exceeds storage bound');
134
+ // A prior publisher may have linked this visible record before its directory fsync failed.
135
+ // Repair that durability boundary before acknowledging a receipt or recovery proof.
136
+ if (syncEntry)
137
+ await this.syncDirectory(directory);
138
+ return JSON.parse(bytes.subarray(0, result.bytesRead).toString('utf8'));
139
+ }
140
+ finally {
141
+ await handle.close();
142
+ }
143
+ }
144
+ epochPath(id, epoch) { return join(this.path(id.slice(0, 64)), `${id}.epochs`, String(epoch)); }
145
+ async epochRead(id, epoch, filename) {
146
+ const directory = this.epochPath(id, epoch);
147
+ for (const path of [join(directory, '..'), directory]) {
148
+ if (!(await lstat(path)).isDirectory())
149
+ refuse('invalid recovery epoch directory');
150
+ }
151
+ const value = await this.readAt(directory, filename);
152
+ await this.syncDirectory(join(directory, '..'));
153
+ return value;
154
+ }
155
+ checks(attempt, secrets) {
156
+ return loadCheckEpoch(attempt, async (epoch, filename) => {
157
+ const value = await this.epochRead(attempt.id, epoch, filename);
158
+ credentialFree(value, secrets);
159
+ return value;
160
+ });
161
+ }
162
+ async ensureEpoch(attempt, previous, secrets = []) {
163
+ const nextId = String(Number(previous?.checkId ?? 0) + 1), epoch = epochOf(nextId);
164
+ const expected = { version: 1, id: attempt.id, digest: attempt.digest, epoch,
165
+ ...(epoch > 1 ? { previous } : {}) };
166
+ credentialFree(expected, secrets);
167
+ const directory = this.epochPath(attempt.id, epoch);
168
+ await mkdir(directory, { recursive: true, mode: 0o700 });
169
+ for (const path of [join(directory, '..'), directory]) {
170
+ if (!(await lstat(path)).isDirectory())
171
+ refuse('invalid recovery epoch directory');
172
+ }
173
+ await this.syncDirectory(join(directory, '..'));
174
+ await this.syncDirectory(this.path(attempt.digest));
175
+ try {
176
+ await this.publishAt(directory, 'marker.json', expected, attempt.digest.slice(0, 2));
177
+ }
178
+ catch (error) {
179
+ if (errorCode(error) !== 'EEXIST')
180
+ throw error;
181
+ }
182
+ verifyCheckEpoch(await this.epochRead(attempt.id, epoch, 'marker.json'), expected, attempt);
183
+ await this.syncDirectory(directory);
184
+ }
185
+ async names(digest, syncBucket = true) {
186
+ if (!/^[a-f0-9]{64}$/.test(digest))
187
+ refuse('invalid publication digest');
188
+ const path = this.path(digest);
189
+ try {
190
+ if (!(await lstat(this.bucket(digest.slice(0, 2)))).isDirectory())
191
+ refuse('invalid digest bucket');
192
+ if (!(await lstat(path)).isDirectory())
193
+ refuse('invalid publication directory');
194
+ }
195
+ catch (error) {
196
+ if (errorCode(error) === 'ENOENT')
197
+ return [];
198
+ throw error;
199
+ }
200
+ if (syncBucket)
201
+ await this.syncDirectory(this.bucket(digest.slice(0, 2)));
202
+ await this.syncDirectory(path);
203
+ const names = [];
204
+ const directory = await opendir(path);
205
+ for await (const item of directory) {
206
+ if (names.length >= MAX_RECORDS)
207
+ refuse('publication record limit reached');
208
+ if ((!item.isFile() && !(item.isDirectory() && item.name.endsWith('.epochs'))) || !/^(?:\.tmp-[a-f0-9-]{36}|[a-f0-9]{64}-[1-9][0-9]*\.(?:(?:intent|outcome|owner-stopped)\.json|epochs))$/.test(item.name)
209
+ || (!item.name.startsWith('.tmp-') && !item.name.startsWith(`${digest}-`)))
210
+ refuse('unrecognized publication state');
211
+ names.push(item.name);
212
+ }
213
+ return names;
214
+ }
215
+ async load(digest, targetId, secrets = []) {
216
+ await this.prepare();
217
+ const selected = await this.history(await this.names(digest), digest, targetId, secrets);
218
+ return selected ? [selected] : [];
219
+ }
220
+ /** Acknowledgment follows one fsync AFTER all verified root reads; no receipt escapes before it. */
221
+ async history(names, digest, targetId, secrets, visit) {
222
+ const selected = await loadBcfHistory(names, name => this.readAt(this.path(digest), name, false), attempt => this.checks(attempt, secrets), targetId, secrets, visit);
223
+ if (names.length)
224
+ await this.syncDirectory(this.path(digest));
225
+ return selected;
226
+ }
227
+ /** Weakly consistent pages: a cursor progresses at the work/byte bound, even without rows. */
228
+ async page(options = {}, secrets = []) {
229
+ await this.prepare();
230
+ const limit = options.limit ?? 100;
231
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1_000)
232
+ refuse('page limit must be between 1 and 1000');
233
+ const match = options.cursor === undefined ? ['00:0:0', '00', '0', '0'] : /^([a-f0-9]{2}):([0-9]{1,4}):([0-9]{1,3})$/.exec(options.cursor);
234
+ if (!match || Number(match[2]) >= DIGEST_SLOTS || Number(match[3]) > MAX_GENERATIONS)
235
+ refuse('invalid page cursor');
236
+ let prefix = Number.parseInt(match[1], 16), slot = Number(match[2]), generation = Number(match[3]);
237
+ let work = 0, bytes = 0;
238
+ const entries = [];
239
+ const cursor = () => `${prefix.toString(16).padStart(2, '0')}:${slot}:${generation}`;
240
+ while (prefix < 256) {
241
+ const bucket = this.bucket(prefix.toString(16).padStart(2, '0'));
242
+ try {
243
+ if (!(await lstat(bucket)).isDirectory())
244
+ refuse('invalid digest bucket');
245
+ }
246
+ catch (error) {
247
+ if (errorCode(error) !== 'ENOENT')
248
+ throw error;
249
+ prefix += 1;
250
+ slot = 0;
251
+ generation = 0;
252
+ continue;
253
+ }
254
+ try {
255
+ while (slot < DIGEST_SLOTS) {
256
+ if (work >= 50_000 || entries.length >= limit)
257
+ return { entries, nextCursor: cursor() };
258
+ work += 1;
259
+ let digest;
260
+ try {
261
+ digest = capacityDigest(await this.readAt(bucket, `slot-${slot}.json`, false));
262
+ }
263
+ catch (error) {
264
+ if (errorCode(error) !== 'ENOENT')
265
+ throw error;
266
+ break; // Claims fill the first free slot and are never deleted: no holes.
267
+ }
268
+ if (!digest.startsWith(prefix.toString(16).padStart(2, '0')))
269
+ refuse('capacity bucket identity mismatch');
270
+ const names = await this.names(digest, false);
271
+ // Each attempt: <=106 marker probes, 32 event probes and bounded root reads.
272
+ const attempts = names.filter(name => name.endsWith('.intent.json')).length;
273
+ if (attempts > MAX_GENERATIONS)
274
+ refuse('excessive attempt generations');
275
+ const cost = 2 * names.length + 142 * attempts;
276
+ if (work + cost > 50_000)
277
+ return { entries, nextCursor: cursor() };
278
+ work += cost;
279
+ let stopped = false;
280
+ // Validate one history once, retaining only bounded public rows and current history state.
281
+ await this.history(names, digest, undefined, secrets, item => {
282
+ if (stopped || item.attempt.generation <= generation)
283
+ return;
284
+ const entry = entryOf(item);
285
+ const size = Buffer.byteLength(JSON.stringify(entry));
286
+ if (entries.length >= limit || bytes + size > 5 * 1024 * 1024) {
287
+ stopped = true;
288
+ return;
289
+ }
290
+ entries.push(entry);
291
+ bytes += size;
292
+ generation = item.attempt.generation;
293
+ });
294
+ if (stopped)
295
+ return { entries, nextCursor: cursor() };
296
+ slot += 1;
297
+ generation = 0;
298
+ }
299
+ }
300
+ finally {
301
+ // Persist all observed slot and digest links AFTER these reads, including
302
+ // concurrent links observed after entering the bucket, before any return.
303
+ await this.syncDirectory(bucket);
304
+ }
305
+ prefix += 1;
306
+ slot = 0;
307
+ generation = 0;
308
+ }
309
+ return { entries };
310
+ }
311
+ }
312
+ //# sourceMappingURL=bcf-publication-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-store.js","sourceRoot":"","sources":["../src/bcf-publication-store.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC7I,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAsB,MAAM,6BAA6B,CAAC;AAC5G,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAY5F,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,MAAM,UAAU,OAAO,CAAC,IAAmB,EAAE,YAAY,GAAG,KAAK;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IACxC,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;QACxF,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC;QAC1I,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpH,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,8FAA8F;AAC9F,MAAM,OAAO,mBAAmB;IACT;IAArB,YAAqB,SAAiB;QAAjB,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAClC,MAAM,CAAC,MAAc,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,CAAC,MAAc,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACtF,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,IAAI,SAAS,CAAC,MAAM,IAAI,GAAG;gBAAE,MAAM,CAAC,iDAAiD,CAAC,CAAC;YACvF,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAM;QACpC,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE;YAAE,MAAM,CAAC,6BAA6B,CAAC,CAAC;QACxF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC9C,MAAM,CAAC,wHAAwH,CAAC,CAAC;YACnI,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QACrD,iFAAiF;QACjF,kFAAkF;QAClF,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,MAAM,CAAC,8CAA8C,CAAC,CAAC;QAC5H,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,MAAM,CAAC,8BAA8B,CAAC,CAAC;YAC/E,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACO,KAAK,CAAC,aAAa,CAAC,SAAiB;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QACjF,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;gBAAS,CAAC;YAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IAChE,CAAC;IACO,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,QAAgB,EAAE,KAAc,EAAE,MAAc,EAAE,QAAqB;QAChH,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,gBAAgB;YAAE,MAAM,CAAC,8BAA8B,CAAC,CAAC;QACxF,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1B,0EAA0E;QAC1E,sGAAsG;QACtG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,iCAAiC,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,UAAU,EAAE,EAAE,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;gBAAS,CAAC;YAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAC7F,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;YACjD,QAAQ,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC;gBAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YAAC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAC9C,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ;oBAAE,OAAO,CAAC,IAAI,CAAC,0DAA0D,EAAE,KAAK,CAAC,CAAC;YACrH,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,KAAc,EAAE,UAA6B,EAAE,EAAE,QAAqB;QACpG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,uGAAuG,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,CAAC,8BAA8B,CAAC,CAAC;QACpK,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE;YAAE,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAC1E,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QACrD,MAAM,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YAC7D,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpG,CAAC,EACC,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;YAAE,MAAM,CAAC,+BAA+B,CAAC,CAAC;QAChF,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,0CAA0C,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxE,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAC9H,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClF,CAAC;IACO,KAAK,CAAC,MAAM,CAAC,SAAiB,EAAE,QAAgB,EAAE,SAAS,GAAG,IAAI;QACxE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QACvH,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,gBAAgB;gBAAE,MAAM,CAAC,oCAAoC,CAAC,CAAC;YACjG,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC5D,IAAI,MAAM,CAAC,SAAS,GAAG,gBAAgB;gBAAE,MAAM,CAAC,8BAA8B,CAAC,CAAC;YAChF,2FAA2F;YAC3F,oFAAoF;YACpF,IAAI,SAAS;gBAAE,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1E,CAAC;gBAAS,CAAC;YAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IACrC,CAAC;IACO,SAAS,CAAC,EAAU,EAAE,KAAa,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChH,KAAK,CAAC,SAAS,CAAC,EAAU,EAAE,KAAa,EAAE,QAAgB;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5C,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,MAAM,CAAC,kCAAkC,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrD,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACO,MAAM,CAAC,OAAyB,EAAE,OAA0B;QAClE,OAAO,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACvD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAAC,OAAO,KAAK,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,OAAyB,EAAE,QAAyB,EAAE,UAA6B,EAAE;QACrG,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACnF,MAAM,QAAQ,GAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK;YACzF,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACvC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpD,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,MAAM,CAAC,kCAAkC,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACrG,IAAI,CAAC;YAAC,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAC7F,OAAO,KAAK,EAAE,CAAC;YAAC,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;QAAC,CAAC;QACjE,gBAAgB,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5F,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IACO,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,UAAU,GAAG,IAAI;QACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,4BAA4B,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC;YACH,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,MAAM,CAAC,uBAAuB,CAAC,CAAC;YACnG,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,MAAM,CAAC,+BAA+B,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YAAC,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YAAC,MAAM,KAAK,CAAC;QAAC,CAAC;QAC5E,IAAI,UAAU;YAAE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC,MAAM,IAAI,WAAW;gBAAE,MAAM,CAAC,kCAAkC,CAAC,CAAC;YAC5E,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,uGAAuG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;mBACrM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;gBAAE,MAAM,CAAC,gCAAgC,CAAC,CAAC;YACvH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,QAAiB,EAAE,UAA6B,EAAE;QAC3E,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzF,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,CAAC;IAED,oGAAoG;IAC5F,KAAK,CAAC,OAAO,CAAC,KAAe,EAAE,MAAc,EAAE,QAA4B,EAAE,OAA0B,EAC7G,KAAqC;QACrC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,EAC9F,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACtE,IAAI,KAAK,CAAC,MAAM;YAAE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,8FAA8F;IAC9F,KAAK,CAAC,IAAI,CAAC,UAA2C,EAAE,EAAE,UAA6B,EAAE;QACvF,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,KAAK;YAAE,MAAM,CAAC,uCAAuC,CAAC,CAAC;QAChH,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,2CAA2C,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3I,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe;YAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACpH,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnG,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;QACxB,MAAM,OAAO,GAAgC,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC;QACrF,OAAO,MAAM,GAAG,GAAG,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACjE,IAAI,CAAC;gBAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE;oBAAE,MAAM,CAAC,uBAAuB,CAAC,CAAC;YAAC,CAAC;YAClF,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ;oBAAE,MAAM,KAAK,CAAC;gBAC/C,MAAM,IAAI,CAAC,CAAC;gBAAC,IAAI,GAAG,CAAC,CAAC;gBAAC,UAAU,GAAG,CAAC,CAAC;gBAAC,SAAS;YAClD,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,IAAI,GAAG,YAAY,EAAE,CAAC;oBAC3B,IAAI,IAAI,IAAI,MAAM,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK;wBAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;oBACxF,IAAI,IAAI,CAAC,CAAC;oBACV,IAAI,MAAc,CAAC;oBACnB,IAAI,CAAC;wBAAC,MAAM,GAAG,cAAc,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,IAAI,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;oBAAC,CAAC;oBACvF,OAAO,KAAK,EAAE,CAAC;wBACb,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ;4BAAE,MAAM,KAAK,CAAC;wBAC/C,MAAM,CAAC,mEAAmE;oBAC5E,CAAC;oBACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;wBAAE,MAAM,CAAC,mCAAmC,CAAC,CAAC;oBAC1G,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBAC9C,6EAA6E;oBAC7E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;oBAC5E,IAAI,QAAQ,GAAG,eAAe;wBAAE,MAAM,CAAC,+BAA+B,CAAC,CAAC;oBACxE,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC;oBAC/C,IAAI,IAAI,GAAG,IAAI,GAAG,MAAM;wBAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;oBACnE,IAAI,IAAI,IAAI,CAAC;oBACb,IAAI,OAAO,GAAG,KAAK,CAAC;oBACpB,2FAA2F;oBAC3F,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;wBAC3D,IAAI,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,UAAU;4BAAE,OAAO;wBAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;wBAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;wBACtD,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;4BAAC,OAAO,GAAG,IAAI,CAAC;4BAAC,OAAO;wBAAC,CAAC;wBAC1F,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBAAC,KAAK,IAAI,IAAI,CAAC;wBAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;oBAC3E,CAAC,CAAC,CAAC;oBACH,IAAI,OAAO;wBAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;oBACtD,IAAI,IAAI,CAAC,CAAC;oBAAC,UAAU,GAAG,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,0EAA0E;gBAC1E,0EAA0E;gBAC1E,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC;YACD,MAAM,IAAI,CAAC,CAAC;YAAC,IAAI,GAAG,CAAC,CAAC;YAAC,UAAU,GAAG,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,105 @@
1
+ import type { Capability } from '@ifc-lite/extensions';
2
+ import type { FetchTransport } from '@ifc-lite/sandbox';
3
+ import type { BcfWriteGateway, BcfWriteIntent } from './bcf-write-gateway.js';
4
+ import type { BcfPublicationFailure } from './bcf-publication.js';
5
+ export interface NativeBcfPublicationOptions {
6
+ directory?: string;
7
+ /** Storage isolation, e.g. a stable authenticated MCP principal. Never a credential. */
8
+ namespace?: string;
9
+ /** Known run secrets: an intent containing one is refused before persistence. */
10
+ secrets?: readonly string[];
11
+ }
12
+ export interface NativeBcfPublicationCheckOptions {
13
+ token?: string;
14
+ networkGrants: readonly Capability[];
15
+ signal?: AbortSignal;
16
+ networkTransport?: FetchTransport;
17
+ /** Operator confirms an unverifiable owner stopped; never overrides an observed live process. */
18
+ confirmOwnerStopped?: boolean;
19
+ /** Operator asserts this read sees the complete target collection in the original write access scope. */
20
+ confirmFullReadAccess?: boolean;
21
+ }
22
+ export type NativeBcfOwnerStatus = 'alive' | 'dead' | 'unknown';
23
+ export interface NativeBcfPublicationCheck {
24
+ at: string;
25
+ /** A match remains a candidate until an explicit reconciliation. */
26
+ result: 'ambiguous' | 'absent' | 'unavailable';
27
+ candidates: {
28
+ guid: string;
29
+ }[];
30
+ /** Present only on complete absence proven under an explicit full-visibility assertion. */
31
+ fullReadAccessConfirmed?: true;
32
+ }
33
+ export interface NativeBcfPublicationEntry {
34
+ id: string;
35
+ intent: BcfWriteIntent;
36
+ state: 'sending' | 'uncertain' | 'failed' | 'done';
37
+ queuedAt: string;
38
+ receipt?: {
39
+ remoteGuid: string;
40
+ at: string;
41
+ evidence: 'response' | 'reconciled';
42
+ };
43
+ failure?: BcfPublicationFailure;
44
+ check?: NativeBcfPublicationCheck;
45
+ ownerStatus?: NativeBcfOwnerStatus;
46
+ }
47
+ export interface NativeBcfPublicationPage {
48
+ entries: NativeBcfPublicationEntry[];
49
+ nextCursor?: string;
50
+ }
51
+ export interface NativeBcfPublicationPageOptions {
52
+ cursor?: string;
53
+ limit?: number;
54
+ }
55
+ export interface NativeBcfWriteGateway extends BcfWriteGateway {
56
+ list(): Promise<NativeBcfPublicationEntry[]>;
57
+ listPage(options?: NativeBcfPublicationPageOptions): Promise<NativeBcfPublicationPage>;
58
+ check(entryId: string, options: NativeBcfPublicationCheckOptions): Promise<NativeBcfPublicationEntry>;
59
+ reconcile(entryId: string, candidateGuid: string): Promise<NativeBcfPublicationEntry>;
60
+ /** Explicitly release an unresolved intent after the latest successful check found no effect. */
61
+ confirmAbsent(entryId: string): Promise<NativeBcfPublicationEntry>;
62
+ }
63
+ /** Stored immutable attempt; PID ownership is conservative and never stolen. */
64
+ export interface StoredBcfAttempt {
65
+ version: 1;
66
+ id: string;
67
+ digest: string;
68
+ generation: number;
69
+ intent: BcfWriteIntent;
70
+ queuedAt: string;
71
+ owner: {
72
+ pid: number;
73
+ host: string;
74
+ boot?: string;
75
+ domain?: string;
76
+ instance?: string;
77
+ };
78
+ }
79
+ export interface StoredBcfOwnerConfirmation {
80
+ version: 1;
81
+ id: string;
82
+ digest: string;
83
+ at: string;
84
+ assertion: 'owner-stopped';
85
+ }
86
+ export interface StoredBcfOutcome {
87
+ version: 1;
88
+ id: string;
89
+ digest: string;
90
+ state: 'done' | 'failed' | 'uncertain';
91
+ receipt?: NativeBcfPublicationEntry['receipt'];
92
+ failure?: BcfPublicationFailure;
93
+ }
94
+ export interface StoredBcfCheck {
95
+ version: 1;
96
+ id: string;
97
+ digest: string;
98
+ checkId: string;
99
+ check: NativeBcfPublicationCheck;
100
+ settlement?: {
101
+ outcome: StoredBcfOutcome;
102
+ proofCheckId: string;
103
+ };
104
+ }
105
+ //# sourceMappingURL=bcf-publication-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-types.d.ts","sourceRoot":"","sources":["../src/bcf-publication-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ export {};
5
+ //# sourceMappingURL=bcf-publication-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-types.js","sourceRoot":"","sources":["../src/bcf-publication-types.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}
@@ -0,0 +1,13 @@
1
+ /** Credential-free failure shape shared with browser publication. */
2
+ export interface BcfPublicationFailure {
3
+ code: 'auth' | 'permission' | 'vocabulary' | 'rejected' | 'no-response' | 'server-error' | 'conflict-exists' | 'interrupted' | 'confirmed-absent' | 'discarded';
4
+ message: string;
5
+ status?: number;
6
+ at: string;
7
+ }
8
+ /** Only valid 4xx refusals are definite; 409, other answers and unqualified denials remain uncertain. */
9
+ export declare function classifyWriteError(error: unknown, at: string): {
10
+ state: 'failed' | 'uncertain';
11
+ failure: BcfPublicationFailure;
12
+ };
13
+ //# sourceMappingURL=bcf-publication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication.d.ts","sourceRoot":"","sources":["../src/bcf-publication.ts"],"names":[],"mappings":"AAIA,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,cAAc,GAAG,iBAAiB,GACxG,aAAa,GAAG,kBAAkB,GAAG,WAAW,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG;IAC9D,KAAK,EAAE,QAAQ,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAC;CAC/D,CAeA"}
@@ -0,0 +1,24 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** Only valid 4xx refusals are definite; 409, other answers and unqualified denials remain uncertain. */
5
+ export function classifyWriteError(error, at) {
6
+ const message = error instanceof Error ? error.message : String(error);
7
+ // Only typed preflight provenance proves that a request never left the host.
8
+ if (error instanceof Error && error.name === 'NetworkDeniedError'
9
+ && error.dispatched === false) {
10
+ return { state: 'failed', failure: { code: 'permission', message, at } };
11
+ }
12
+ const value = error instanceof Error && /ApiError$|AuthenticationError$/.test(error.name)
13
+ ? error.status : undefined;
14
+ const status = typeof value === 'number' && Number.isInteger(value) ? value : undefined;
15
+ if (status === undefined || status < 400 || status > 599)
16
+ return { state: 'uncertain', failure: { code: 'no-response', message, at } };
17
+ if (status >= 500)
18
+ return { state: 'uncertain', failure: { code: 'server-error', message, status, at } };
19
+ if (status === 409)
20
+ return { state: 'uncertain', failure: { code: 'conflict-exists', message, status, at } };
21
+ const code = status === 401 ? 'auth' : status === 403 ? 'permission' : 'rejected';
22
+ return { state: 'failed', failure: { code, message, status, at } };
23
+ }
24
+ //# sourceMappingURL=bcf-publication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication.js","sourceRoot":"","sources":["../src/bcf-publication.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAW/D,yGAAyG;AACzG,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,EAAU;IAG3D,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,6EAA6E;IAC7E,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB;WAC3D,KAA0C,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;QACtE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC;IAC3E,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,YAAY,KAAK,IAAI,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QACvF,CAAC,CAAE,KAAsC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC;IACvI,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;IACzG,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;IAC7G,MAAM,IAAI,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;IAClF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;AACrE,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The one path every `bcf.*` write node takes to the server (#6896).
3
+ *
4
+ * A BCF create is not idempotent: a lost response after the server committed
5
+ * leaves a real topic or comment behind, and the node is `volatile`, so a
6
+ * plain rerun would create it again. A host that keeps durable publication
7
+ * state (the viewer) supplies `FlowHost.bcfWrites`: it records the intent
8
+ * before sending, the receipt after, and refuses to resend a write whose
9
+ * earlier attempt has an unknown outcome until someone reconciles it. A host
10
+ * without that state still never retries, and names the unknown outcome
11
+ * instead of reporting a plain failure.
12
+ */
13
+ import type { BcfCommentWriteDto, BcfTopicWriteDto } from '@ifc-lite/bcf-api';
14
+ import type { Ctx } from './host.js';
15
+ /** What a node is about to write, without the bearer token. */
16
+ export interface BcfWriteIntent {
17
+ readonly nodeType: string;
18
+ readonly operation: 'createTopic' | 'createComment';
19
+ /** Base URL up to but excluding the version segment, as the node was configured. */
20
+ readonly baseUrl: string;
21
+ readonly version: string;
22
+ readonly projectId: string;
23
+ /** The topic a comment is written to. */
24
+ readonly topicGuid?: string;
25
+ readonly payload: BcfTopicWriteDto | BcfCommentWriteDto;
26
+ }
27
+ /**
28
+ * Host-owned durable write path. `write` must persist the intent before
29
+ * calling `send`, persist the receipt or failure after, and reject without
30
+ * calling `send` when an identical earlier write is still unresolved.
31
+ */
32
+ export interface BcfWriteGateway {
33
+ write<T extends {
34
+ guid: string;
35
+ }>(intent: BcfWriteIntent, send: () => Promise<T>, secrets?: readonly string[]): Promise<T>;
36
+ }
37
+ /** Send one write through the host gateway, or directly with explicit unknown-outcome reporting. */
38
+ export declare function sendBcfWrite<T extends {
39
+ guid: string;
40
+ }>(ctx: Ctx, intent: BcfWriteIntent, send: () => Promise<T>, secrets?: readonly string[]): Promise<T>;
41
+ //# sourceMappingURL=bcf-write-gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-write-gateway.d.ts","sourceRoot":"","sources":["../src/bcf-write-gateway.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG9E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAKrC,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,eAAe,CAAC;IACpD,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,kBAAkB,CAAC;CACzD;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,CAAC,SAAS;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5H;AAED,oGAAoG;AACpG,wBAAsB,YAAY,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAC3D,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,GAAE,SAAS,MAAM,EAAO,GAC9B,OAAO,CAAC,CAAC,CAAC,CA4DZ"}