@lapxo/bound 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.
Files changed (333) hide show
  1. package/CITATION.cff +1 -1
  2. package/README.md +20 -3
  3. package/TARGET.bound +85 -47
  4. package/dist/cli/accept.js +61 -590
  5. package/dist/cli/act-result.js +3 -103
  6. package/dist/cli/args.js +3 -44
  7. package/dist/cli/custodian.js +2 -29
  8. package/dist/cli/host.js +4 -32
  9. package/dist/cli/names.js +1 -12
  10. package/dist/cli/native-descendant.js +1 -19
  11. package/dist/cli/native.js +3 -60
  12. package/dist/cli/observe.js +1 -13
  13. package/dist/cli/owner.js +3 -139
  14. package/dist/cli/pass.js +22 -321
  15. package/dist/cli/place.js +6 -282
  16. package/dist/cli/release-result.js +3 -80
  17. package/dist/cli/retained-judgment.js +1 -25
  18. package/dist/cli/standing-result.js +4 -19
  19. package/dist/cli/takes.js +10 -112
  20. package/dist/cli/verb.d.ts +1 -2
  21. package/dist/cli/verb.js +85 -684
  22. package/dist/engine/computation.js +2 -0
  23. package/dist/engine/conformance.js +4 -0
  24. package/dist/engine/encoding.js +1 -2
  25. package/dist/engine/index.d.ts +1 -13
  26. package/dist/engine/index.js +2 -11
  27. package/dist/engine/object.js +1 -38
  28. package/dist/engine/ports.js +2 -117
  29. package/dist/fold/admission-history.js +1 -17
  30. package/dist/fold/bootstrap-anchor.js +1 -28
  31. package/dist/fold/ceilings.js +1 -142
  32. package/dist/fold/claims.js +2 -132
  33. package/dist/fold/closed.js +24 -235
  34. package/dist/fold/configures.js +1 -25
  35. package/dist/fold/digests.js +10 -226
  36. package/dist/fold/evidence.js +1 -22
  37. package/dist/fold/fold-worker.js +1 -13
  38. package/dist/fold/kept.js +12 -173
  39. package/dist/fold/keys.js +3 -91
  40. package/dist/fold/laid.js +3 -90
  41. package/dist/fold/nos.js +1 -48
  42. package/dist/fold/object.js +1 -2
  43. package/dist/fold/observed.js +28 -534
  44. package/dist/fold/opened.js +1 -33
  45. package/dist/fold/own.js +3 -217
  46. package/dist/fold/paid.js +1 -92
  47. package/dist/fold/place-inputs.js +1 -70
  48. package/dist/fold/places.js +3 -100
  49. package/dist/fold/rank.js +1 -9
  50. package/dist/fold/reach.js +1 -83
  51. package/dist/fold/readers.js +6 -142
  52. package/dist/fold/receipts.js +1 -47
  53. package/dist/fold/region-declarations.js +1 -13
  54. package/dist/fold/region.js +8 -286
  55. package/dist/fold/release-policy.js +1 -101
  56. package/dist/fold/resolved.js +6 -145
  57. package/dist/fold/roles.js +2 -59
  58. package/dist/fold/second.js +4 -71
  59. package/dist/fold/shards.js +12 -100
  60. package/dist/fold/signed.js +3 -81
  61. package/dist/fold/signers.js +1 -54
  62. package/dist/fold/stranger.js +6 -24
  63. package/dist/fold/views.js +1 -66
  64. package/dist/fold/wire.js +1 -46
  65. package/dist/fold/zoom.js +3 -81
  66. package/dist/host/act-cost.js +1 -25
  67. package/dist/host/adapters/keys/ed25519.js +1 -30
  68. package/dist/host/adapters/modules/javascript.js +1 -50
  69. package/dist/host/adapters/transport/http.js +1 -28
  70. package/dist/host/admitted-place.js +1 -35
  71. package/dist/host/archive.js +1 -152
  72. package/dist/host/call-context.js +1 -14
  73. package/dist/host/capsule-process.js +2 -62
  74. package/dist/host/capsule.js +9 -171
  75. package/dist/host/cell-receipts.js +12 -128
  76. package/dist/host/command-server.js +4 -0
  77. package/dist/host/commit-result.js +1 -5
  78. package/dist/host/content-needed.js +1 -8
  79. package/dist/host/content-store.js +1 -31
  80. package/dist/host/contextual-place.js +2 -72
  81. package/dist/host/digest.js +2 -15
  82. package/dist/host/hash.js +1 -9
  83. package/dist/host/host-controls.js +1 -19
  84. package/dist/host/in-process-act.js +3 -84
  85. package/dist/host/in-process-context.js +3 -91
  86. package/dist/host/in-process-root.js +6 -84
  87. package/dist/host/in-process.js +4 -55
  88. package/dist/host/index.d.ts +1 -15
  89. package/dist/host/index.js +1 -7
  90. package/dist/host/io.js +1 -11
  91. package/dist/host/lifetime.js +1 -79
  92. package/dist/host/located.js +6 -105
  93. package/dist/host/native/authority-card-view.js +5 -0
  94. package/dist/host/native/authority-card.js +1 -0
  95. package/dist/host/native/bounded-file.js +1 -32
  96. package/dist/host/native/command.js +1 -91
  97. package/dist/host/native/control-bridge-worker.js +2 -88
  98. package/dist/host/native/control-bridge.js +1 -110
  99. package/dist/host/native/control-selection.js +1 -32
  100. package/dist/host/native/custody.js +1 -91
  101. package/dist/host/native/deadline.js +1 -28
  102. package/dist/host/native/descendants.js +1 -528
  103. package/dist/host/native/generated-custodian.js +5 -267
  104. package/dist/host/native/generated.js +1 -379
  105. package/dist/host/native/image.js +1 -45
  106. package/dist/host/native/installed-package.d.ts +1 -0
  107. package/dist/host/native/installed-package.js +5 -0
  108. package/dist/host/native/jobs.js +2 -148
  109. package/dist/host/native/loader.js +1 -269
  110. package/dist/host/native/materialize.js +1 -175
  111. package/dist/host/native/module-closure.js +1 -130
  112. package/dist/host/native/module-delivery.d.ts +1 -62
  113. package/dist/host/native/module-delivery.js +1 -151
  114. package/dist/host/native/module-inventory.js +2 -0
  115. package/dist/host/native/module-syntax.js +1 -69
  116. package/dist/host/native/native-binary.js +1 -115
  117. package/dist/host/native/native-program.js +1 -72
  118. package/dist/host/native/node-jobs.js +3 -187
  119. package/dist/host/native/node-launch.js +1 -159
  120. package/dist/host/native/preload.js +1 -45
  121. package/dist/host/native/probes.js +1 -0
  122. package/dist/host/native/reading-witness-admission.js +5 -0
  123. package/dist/host/native/reading.js +1 -249
  124. package/dist/host/native/receipt-environment.js +1 -41
  125. package/dist/host/native/references.js +1 -30
  126. package/dist/host/native/root.js +1 -37
  127. package/dist/host/native/route.js +1 -216
  128. package/dist/host/native/runtime.js +1 -9
  129. package/dist/host/native-place-state.js +1 -0
  130. package/dist/host/native-reader-context.js +1 -8
  131. package/dist/host/native-receiver.js +1 -25
  132. package/dist/host/objects.js +1 -38
  133. package/dist/host/order.js +1 -2
  134. package/dist/host/persistent-host.js +1 -0
  135. package/dist/host/physical-lines.d.ts +1 -0
  136. package/dist/host/physical-lines.js +1 -0
  137. package/dist/host/place-act-transaction.js +4 -78
  138. package/dist/host/place-clock-selection.js +5 -124
  139. package/dist/host/ports/ingress.js +2 -57
  140. package/dist/host/ports/local-act.js +5 -183
  141. package/dist/host/ports/place-act.js +1 -134
  142. package/dist/host/ports/publication.js +1 -56
  143. package/dist/host/ports/signing.js +1 -74
  144. package/dist/host/ports/store.js +1 -18
  145. package/dist/host/ports/transport.js +1 -48
  146. package/dist/host/process-lifetime.js +1 -17
  147. package/dist/host/profile-composition.d.ts +1 -0
  148. package/dist/host/profile-composition.js +2 -0
  149. package/dist/host/provide.js +1 -183
  150. package/dist/host/read-only.js +1 -9
  151. package/dist/host/reading-closures.js +7 -227
  152. package/dist/host/reading-context.js +1 -53
  153. package/dist/host/reading-identity-types.js +0 -0
  154. package/dist/host/reading-identity.js +3 -0
  155. package/dist/host/reading-preparation.js +6 -0
  156. package/dist/host/reference-authenticated.d.ts +1 -40
  157. package/dist/host/reference-authenticated.js +3 -100
  158. package/dist/host/reference-contracts.js +1 -6
  159. package/dist/host/reference-export.js +6 -81
  160. package/dist/host/reference-native-api.d.ts +1 -3
  161. package/dist/host/reference-native-api.js +1 -3
  162. package/dist/host/reference-native.js +1 -74
  163. package/dist/host/reference-profile.js +1 -63
  164. package/dist/host/reference-standing.js +2 -18
  165. package/dist/host/reference.js +1 -24
  166. package/dist/host/refusals.js +2 -43
  167. package/dist/host/release.js +4 -256
  168. package/dist/host/root-clock-source.js +1 -307
  169. package/dist/host/selected-capsules.js +1 -50
  170. package/dist/host/selected-topos.js +1 -80
  171. package/dist/host/signature-era.js +1 -12
  172. package/dist/host/signing.js +2 -48
  173. package/dist/host/source-content.js +2 -111
  174. package/dist/host/standing-carrier.js +1 -18
  175. package/dist/host/standing-projection.js +1 -50
  176. package/dist/host/timing.js +1 -7
  177. package/dist/host/walk.js +20 -193
  178. package/dist/host/work-trace.js +1 -0
  179. package/dist/judge/late.js +1 -33
  180. package/dist/judge/take.js +2 -75
  181. package/dist/judge/widening.js +1 -25
  182. package/dist/land/act.js +8 -336
  183. package/dist/land/alias.js +1 -41
  184. package/dist/land/held.js +1 -23
  185. package/dist/land/inert.js +1 -33
  186. package/dist/land/leaving.js +1 -55
  187. package/dist/land/ledger.js +6 -188
  188. package/dist/land/owned.js +4 -66
  189. package/dist/land/sign.js +1 -53
  190. package/dist/land/standing-pin.js +1 -49
  191. package/dist/land/vouched.js +1 -112
  192. package/dist/land/withdraw.js +1 -24
  193. package/dist/observe/files.js +1 -88
  194. package/dist/observe/identity.js +1 -61
  195. package/dist/observe/match.js +1 -8
  196. package/dist/observe/regions.js +7 -306
  197. package/dist/observe/run.js +1 -41
  198. package/dist/observe/runner.js +4 -101
  199. package/dist/public-types.d.ts +2019 -0
  200. package/dist/render/capsule.js +1 -30
  201. package/dist/render/field.js +1 -40
  202. package/dist/render/names.js +1 -4
  203. package/dist/render/open.js +1 -61
  204. package/dist/render/page.js +1 -7
  205. package/dist/render/receipt-projection.js +1 -0
  206. package/dist/render/receipts.js +1 -47
  207. package/dist/render/shape.js +1 -74
  208. package/dist/render/target.js +4 -52
  209. package/dist/render/view.js +7 -197
  210. package/dist/vendor/bundle.json +1 -0
  211. package/dist/vendor/library14.js +1 -0
  212. package/dist/vendor/object-provider.js +42 -0
  213. package/dist/vendor/runtime.js +61 -0
  214. package/dist/wasm/adapter.d.ts +1 -51
  215. package/dist/wasm/adapter.js +1 -180
  216. package/dist/wasm/node-worker.js +1 -13
  217. package/dist/wasm/object.js +1 -76
  218. package/dist/wasm/worker.js +1 -7
  219. package/docs/contracts/authenticated-reference.publication.json +1 -1
  220. package/docs/contracts/authority-preflight.md +17 -0
  221. package/docs/contracts/authority-preflight.publication.json +25 -0
  222. package/docs/contracts/closure-delivery.md +1 -1
  223. package/docs/contracts/closure-delivery.publication.json +1 -1
  224. package/docs/contracts/conformance.json +142 -0
  225. package/docs/contracts/determinism.bound +9 -0
  226. package/docs/contracts/engine-object-projection.publication.json +1 -1
  227. package/docs/contracts/engine.md +21 -1
  228. package/docs/contracts/installed-package.md +21 -0
  229. package/docs/contracts/installed-package.publication.json +25 -0
  230. package/docs/contracts/materialized-leaf-sequence.md +15 -0
  231. package/docs/contracts/materialized-leaf-sequence.publication.json +25 -0
  232. package/docs/contracts/module-inventory.md +15 -0
  233. package/docs/contracts/module-inventory.publication.json +25 -0
  234. package/docs/contracts/native-host.md +29 -1
  235. package/docs/contracts/native-host.publication.json +4 -4
  236. package/docs/contracts/native-probes.md +13 -0
  237. package/docs/contracts/native-probes.publication.json +25 -0
  238. package/docs/contracts/native-publication.inventory.json +10 -1
  239. package/docs/contracts/native-view-batch.md +17 -0
  240. package/docs/contracts/native-view-batch.publication.json +25 -0
  241. package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
  242. package/docs/contracts/physical-lines.md +19 -0
  243. package/docs/contracts/physical-lines.publication.json +25 -0
  244. package/docs/contracts/profile-composition.md +17 -0
  245. package/docs/contracts/profile-composition.publication.json +25 -0
  246. package/docs/contracts/profile-preparation-native-meaning.md +9 -0
  247. package/docs/contracts/publication.md +12 -0
  248. package/docs/contracts/reading-identity.md +61 -0
  249. package/docs/contracts/reading-identity.publication.json +25 -0
  250. package/docs/contracts/reading-witness-admission.md +49 -0
  251. package/docs/contracts/readme.publication.json +1 -1
  252. package/docs/contracts/reference-port.md +11 -0
  253. package/docs/contracts/reference-port.publication.json +1 -1
  254. package/docs/contracts/refusals.bound +346 -94
  255. package/docs/contracts/refusals.md +119 -39
  256. package/docs/contracts/refusals.publication.json +2 -2
  257. package/docs/contracts/views.md +8 -0
  258. package/docs/reference.md +9 -0
  259. package/licenses/wasm/{fast-text-encoding.txt → NOTICE.txt} +111 -0
  260. package/package.json +84 -34
  261. package/receipts.bound +12952 -10449
  262. package/samples/authority-preflight/no.json +6 -0
  263. package/samples/authority-preflight/yes.json +30 -0
  264. package/samples/engine-alphabet/reader.js +3 -1457
  265. package/samples/engine-alphabet/receipts.bound +7 -7
  266. package/samples/engine-interval/reader.js +3 -1457
  267. package/samples/engine-interval/receipts.bound +7 -7
  268. package/samples/installed-package/consumer.mjs +29 -0
  269. package/samples/installed-package/fixture.json +48 -0
  270. package/samples/installed-package/no.json +10 -0
  271. package/samples/installed-package/yes.json +52 -0
  272. package/samples/materialized-leaf-sequence/no.json +11 -0
  273. package/samples/materialized-leaf-sequence/yes.json +10 -0
  274. package/samples/module-inventory/yes.json +28 -0
  275. package/samples/native/physical-line-reader.mjs +1 -0
  276. package/samples/native/physical-line-reader.source.mjs +13 -0
  277. package/samples/native-host/no.json +6 -1
  278. package/samples/native-host/yes.json +18 -1
  279. package/samples/native-probes/inputs/inspection.json +28 -0
  280. package/samples/native-probes/no.json +7 -0
  281. package/samples/native-probes/yes.json +28 -0
  282. package/samples/native-view-batch/no.json +14 -0
  283. package/samples/native-view-batch/yes.json +10 -0
  284. package/samples/no/engine-order/reader.js +3 -1457
  285. package/samples/no/module-inventory/no.json +10 -0
  286. package/samples/physical-lines/no.json +5 -0
  287. package/samples/physical-lines/yes.json +9 -0
  288. package/samples/profile-composition/no.json +6 -0
  289. package/samples/profile-composition/yes.json +14 -0
  290. package/samples/reading-identity/no.json +26 -0
  291. package/samples/reading-identity/yes.json +69 -0
  292. package/vectors/native/authority-preflight.vector.json +55 -0
  293. package/vectors/native/installed-package.vector.json +31 -0
  294. package/vectors/native/materialized-leaf-sequence.vector.json +31 -0
  295. package/vectors/native/module-inventory.vector.json +56 -0
  296. package/vectors/native/native-host.vector.json +214 -0
  297. package/vectors/native/native-probes.vector.json +31 -0
  298. package/vectors/native/native-view-batch.vector.json +31 -0
  299. package/vectors/native/physical-lines.vector.json +105 -0
  300. package/vectors/native/profile-composition.vector.json +53 -0
  301. package/vectors/native/reading-identity.vector.json +139 -0
  302. package/vectors/native/refusals.vector.json +138 -0
  303. package/vendor/syntax/LICENSE.md +7 -0
  304. package/vendor/syntax/parser.js +1 -0
  305. package/.github/workflows/release.yml +0 -67
  306. package/.github/workflows/test.yml +0 -35
  307. package/dist/engine/object.d.ts +0 -17
  308. package/dist/engine/ports.d.ts +0 -37
  309. package/dist/fold/claims.d.ts +0 -29
  310. package/dist/host/call-context.d.ts +0 -20
  311. package/dist/host/commit-result.d.ts +0 -6
  312. package/dist/host/in-process-act.d.ts +0 -82
  313. package/dist/host/in-process-context.d.ts +0 -46
  314. package/dist/host/in-process-root.d.ts +0 -117
  315. package/dist/host/in-process.d.ts +0 -41
  316. package/dist/host/native/module-closure.d.ts +0 -35
  317. package/dist/host/native-receiver.d.ts +0 -19
  318. package/dist/host/place-act-transaction.d.ts +0 -24
  319. package/dist/host/place-clock-selection.d.ts +0 -55
  320. package/dist/host/ports/local-act.d.ts +0 -44
  321. package/dist/host/ports/place-act.d.ts +0 -49
  322. package/dist/host/ports/publication.d.ts +0 -10
  323. package/dist/host/reference-export.d.ts +0 -33
  324. package/dist/host/reference-native.d.ts +0 -30
  325. package/dist/host/reference-profile.d.ts +0 -23
  326. package/dist/host/refusals.d.ts +0 -14
  327. package/dist/host/root-clock-source.d.ts +0 -86
  328. package/licenses/wasm/jitl-quickjs-ffi-types.txt +0 -21
  329. package/licenses/wasm/jitl-quickjs-wasmfile-release-sync.txt +0 -47
  330. package/licenses/wasm/quickjs-emscripten-core.txt +0 -21
  331. package/licenses/wasm/topos.txt +0 -21
  332. /package/{licenses/wasm/bound.txt → dist/vendor/28cba430228db1c04f446c93f81b09a2705d6bf3e222d35adbe5a4cee4061884.LICENSE} +0 -0
  333. /package/{licenses/wasm/obligations.txt → dist/vendor/7aca161279d14bc0e054dcc281cd110aeb95be2e026b42fdf527a260e58b2aae.LICENSE} +0 -0
@@ -1,124 +1,5 @@
1
- /** Fixed HOST construction for the opt-in SDK clock profile. No CLI activation,
2
- * inferred genesis, new wire fields, or packet-supplied signature verifier. */
3
- import { createHash } from 'node:crypto';
4
- import { PLACE_ACT_CONTEXT } from '@lapxo/topos/core';
5
- import { canonical, signedBytes, wireAt } from '@lapxo/topos/wire';
6
- import { foldClaims, isConfig, fieldOf, parsedLine as parse } from "../fold/claims.js";
7
- import { signatureEraOf as eraOf } from "./signature-era.js";
8
- import { authorityFor } from "../fold/signers.js";
9
- import { verifyBytes } from "./adapters/keys/ed25519.js";
10
- import { verifiesOwnerLine } from "../land/sign.js";
11
- import { placeActHeads } from "./ports/place-act.js";
12
- const fail = (why) => { throw Error('REFUSE·clock selection ' + why); };
13
- const digest = (s) => 'sha256:' + createHash('sha256').update(s).digest('hex');
14
- const text = (s) => typeof s === 'string' && s.length > 0;
15
- const clock = (s) => { if (typeof s !== 'string' || !/^(0|[1-9][0-9]*)$/.test(s) || !Number.isSafeInteger(Number(s)))
16
- fail('unknown clock'); return Number(s); };
17
- // Exact-byte parsing returns frozen values. Retain only this pure syntax verdict;
18
- // history, signatures, authority windows, clocks and protected rereads stay fresh.
19
- const canonicalValues = new WeakSet();
20
- const f = (line) => { const got = parse(line); if (got.kind !== 'fact')
21
- return fail('noncanonical history'); if (!canonicalValues.has(got.value)) {
22
- if (canonical(got.value.fields, got.value.version) !== line)
23
- fail('noncanonical history');
24
- canonicalValues.add(got.value);
25
- } return got.value.fields; };
26
- /** Root chooses selector and anchors/resources from its authenticated standing.
27
- * Selection must be ROOT signed; a world's signature grants no host capability. */
28
- export function hostClockSelection(input) {
29
- const b = input.resources;
30
- if (!b || Object.keys(b).sort().join(',') !== 'bytes,lines,places' || Object.values(b).some(n => !Number.isSafeInteger(n) || n < 1))
31
- fail('missing input resources');
32
- const inherited = input.inherited;
33
- if (!inherited?.clock || Object.keys(inherited.clock).sort().join(',') !== 'bytes,placements,policies,proofs,records,signers' || !inherited.storage || Object.keys(inherited.storage).sort().join(',') !== 'acts,bytes' || [...Object.values(inherited.clock), ...Object.values(inherited.storage)].some(n => !Number.isSafeInteger(n) || n < 1))
34
- fail('missing inherited resource authority');
35
- if (input.history.length + input.legacyOriginals.length > b.lines)
36
- fail('input line budget');
37
- let bytes = 0;
38
- for (const line of [...input.history, ...input.legacyOriginals]) {
39
- if (typeof line !== 'string' || line.length > b.bytes || (bytes += Buffer.byteLength(line)) > b.bytes)
40
- fail('input byte budget');
41
- }
42
- const snapshots = new Map();
43
- for (const original of input.history) {
44
- const epoch = clock(f(original).epoch ?? fail('history clock absent'));
45
- let authority = snapshots.get(epoch);
46
- if (!authority) {
47
- const before = input.history.filter(l => !isConfig(l) || clock(f(l).epoch ?? fail('history clock absent')) <= epoch);
48
- authority = authorityFor(before, input.anchor, eraOf(foldClaims(before.filter(l => fieldOf(l, 'scope').startsWith('wire/'))).standing).admitted);
49
- snapshots.set(epoch, authority);
50
- }
51
- if (authority.of(original).kind !== 'admitted')
52
- fail('history not authenticated at admission');
53
- }
54
- const live = foldClaims(input.history.filter(isConfig)).standing.filter(l => fieldOf(l, 'value') !== 'withdraw');
55
- const ids = live.filter(l => { const p = f(l); return p.scope === input.profileSelector && p.measure === 'id'; });
56
- if (ids.length !== 1 || f(ids[0]).value !== PLACE_ACT_CONTEXT || f(ids[0]).role !== 'writes' || f(ids[0]).form !== 'alphabet' || f(ids[0]).by !== input.anchor.id)
57
- fail('missing/ambiguous clock profile id');
58
- const rows = live.filter(l => { const p = f(l); return p.scope === input.selector && p.measure === 'text'; });
59
- if (rows.length !== 1)
60
- fail('missing/ambiguous Root selector');
61
- const line = rows[0], fields = f(line);
62
- if (fields.by !== input.anchor.id || fields.role !== 'writes' || fields.form !== 'alphabet' || fields.value !== 'lock' || !verifiesOwnerLine(line, input.anchor.publicKey, input.algorithms))
63
- fail('selector is not Root signed');
64
- if (!fields.about || fields.about.length > b.bytes)
65
- fail('missing selector body');
66
- let selection;
67
- try {
68
- selection = JSON.parse(fields.about);
69
- }
70
- catch {
71
- return fail('selector JSON');
72
- }
73
- if (!selection || Object.keys(selection).sort().join(',') !== 'budget,digestAlgorithm,initial,namespace,profile,receiptScope,receiptSigner,regionFamily,storageBudget' || selection.profile !== PLACE_ACT_CONTEXT || selection.digestAlgorithm !== 'sha256' || !text(selection.namespace) || !text(selection.regionFamily) || !text(selection.receiptSigner) || !text(selection.receiptScope) || !Array.isArray(selection.initial) || !selection.initial.length || selection.initial.length > b.places)
74
- fail('unsupported selector shape');
75
- if (JSON.stringify(selection) !== fields.about)
76
- fail('noncanonical selector JSON');
77
- if (!selection.budget || Object.keys(selection.budget).sort().join(',') !== 'bytes,placements,policies,proofs,records,signers' || Object.values(selection.budget).some(n => !Number.isSafeInteger(n) || n < 1) || !selection.storageBudget || Object.keys(selection.storageBudget).sort().join(',') !== 'acts,bytes' || Object.values(selection.storageBudget).some(n => !Number.isSafeInteger(n) || n < 1))
78
- fail('missing selected resources');
79
- for (const name of ['bytes', 'records', 'placements', 'policies', 'proofs', 'signers'])
80
- if (selection.budget[name] > inherited.clock[name])
81
- fail('clock resource exceeds inherited ' + name);
82
- for (const name of ['acts', 'bytes'])
83
- if (selection.storageBudget[name] > inherited.storage[name])
84
- fail('storage resource exceeds inherited ' + name);
85
- if (selection.budget.bytes > b.bytes || selection.storageBudget.bytes > b.bytes || selection.budget.records > b.lines || selection.budget.placements > b.places)
86
- fail('selected resources exceed input authority');
87
- const wire = wireAt(live.map(f), Number.MAX_SAFE_INTEGER);
88
- if (!wire || !wire.digests.has(selection.digestAlgorithm))
89
- fail('digest algorithm not declared');
90
- const authority = authorityFor(input.history, input.anchor, input.algorithms);
91
- if (!input.history.includes(input.authorityCheckpoint) || !isConfig(input.authorityCheckpoint))
92
- fail('missing authenticated Root authority checkpoint');
93
- const checkpointEpoch = clock(f(input.authorityCheckpoint).epoch ?? fail('Root authority clock absent'));
94
- if (snapshots.get(checkpointEpoch)?.of(input.authorityCheckpoint).kind !== 'admitted')
95
- fail('Root checkpoint not admitted at original epoch');
96
- const epoch = clock(f(input.authorityCheckpoint).epoch ?? fail('Root authority clock absent'));
97
- if (input.history.filter(isConfig).some(l => clock(f(l).epoch ?? fail('history clock absent')) > epoch))
98
- fail('authority checkpoint precedes Root configuration');
99
- const prefix = digest(input.history.join('\n') + '\n'), head = digest(live.join('\n') + '\n');
100
- const policies = [...new Set(live.map(digest))].sort();
101
- if (policies.length > selection.budget.policies)
102
- fail('actual dependency budget');
103
- const root = { namespace: selection.namespace, snapshot: digest(JSON.stringify([prefix, head, String(epoch)])), epoch: String(epoch), prefix, head, policies };
104
- const initialHeads = selection.initial.map(i => { if (!i || !i.receiver || !i.origin || !text(i.receiver.identity) || !text(i.origin.prefix) || !text(i.place))
105
- fail('unknown initial namespace'); const parts = i.place.split('/'); if (i.place !== '.' && (parts.length < 2 || parts.at(-1) !== 'TARGET.bound' || parts.some(s => s === '' || s === '.' || s === '..')))
106
- fail('unknown initial namespace'); clock(i.receiver.epoch); clock(i.origin.epoch); return { place: i.place, identity: i.receiver.identity, epoch: i.receiver.epoch }; });
107
- if (new Set(initialHeads.map(h => h.place)).size !== initialHeads.length)
108
- fail('duplicate namespace');
109
- const legacy = new Set(input.legacyOriginals.map(l => digest(signedBytes(f(l)))));
110
- let heads = [];
111
- const contract = { budget: selection.budget, root, signers: authority.admitted, places: initialHeads.map(h => h.place), regionFamily: selection.regionFamily, receiptSigner: selection.receiptSigner, receiptScope: selection.receiptScope, digest,
112
- verifiesRootContext: c => JSON.stringify(c) === JSON.stringify(root),
113
- verifiesNamespaceAdmission: p => { if (p === '.')
114
- return true; const parts = p.split('/'); if (parts.length < 2 || parts.pop() !== 'TARGET.bound' || parts.some(s => s === '' || s === '.' || s === '..'))
115
- return false; const n = parts.join('/'), rows = live.filter(l => f(l).scope === selection.regionFamily + '/' + n); if (rows.length !== 1)
116
- return false; const v = f(rows[0]); return v.role === 'writes' && v.form === 'alphabet' && v.measure === 'coordinates' && v.value === n + '/**'; },
117
- verifiesNewLocalPrefix: (p, prefix, epoch, originals) => { const h = heads.find(h => h.place === p), i = selection.initial.find(i => i.place === p); if (!h || !i || originals.some(l => legacy.has(digest(signedBytes(f(l))))))
118
- return false; return h.identity === i.receiver.identity ? prefix === i.origin.prefix && epoch === i.origin.epoch : prefix === h.identity && clock(epoch) === clock(h.epoch) + 1; },
119
- verifiesOriginal: (l, s) => verifiesOwnerLine(l, s.publicKey, input.algorithms),
120
- verifiesProof: (text, signature, s) => verifyBytes(text, s.publicKey, signature, input.algorithms), };
121
- heads = input.authenticatedReceiverHeads ?? placeActHeads(input.store, initialHeads, { contract, historical: input.historical }, selection.storageBudget);
122
- const trust = { contract, initialHeads, current: () => { const fresh = hostClockSelection({ ...input, ...input.readCurrent(), authenticatedReceiverHeads: undefined }); return { root: fresh.trust.contract.root, heads: placeActHeads(input.store, fresh.trust.initialHeads, fresh.trust, fresh.selection.storageBudget) }; }, historical: input.historical };
123
- return { selection, trust };
124
- }
1
+ var U=Object.defineProperty;var l=(t,s)=>U(t,"name",{value:s,configurable:!0});import{createHash as V}from"node:crypto";import{library6_PLACE_ACT_CONTEXT as _}from"../vendor/runtime.js";import{library14_canonical as $,library14_signedBytes as F,library14_wireAt as q}from"../vendor/runtime.js";import{foldClaims as J,isConfig as S,fieldOf as H,parsedLine as D}from"../fold/claims.js";import{signatureEraOf as Q}from"./signature-era.js";import{authorityFor as I}from"../fold/signers.js";import{verifyBytes as Y}from"./adapters/keys/ed25519.js";import{verifiesOwnerLine as L}from"../land/sign.js";import{placeActHeads as P}from"./ports/place-act.js";const i=l(t=>{throw Error("REFUSE\xB7clock selection "+t)},"fail"),y=l(t=>"sha256:"+V("sha256").update(t).digest("hex"),"digest"),m=l(t=>typeof t=="string"&&t.length>0,"text"),h=l(t=>((typeof t!="string"||!/^(0|[1-9][0-9]*)$/.test(t)||!Number.isSafeInteger(Number(t)))&&i("unknown clock"),Number(t)),"clock"),G=new WeakSet,c=l(t=>{const s=D(t);return s.kind!=="fact"?i("noncanonical history"):(G.has(s.value)||($(s.value.fields,s.value.version)!==t&&i("noncanonical history"),G.add(s.value)),s.value.fields)},"f");function Z(t){const s=t.resources;(!s||Object.keys(s).sort().join(",")!=="bytes,lines,places"||Object.values(s).some(e=>!Number.isSafeInteger(e)||e<1))&&i("missing input resources");const f=t.inherited;(!f?.clock||Object.keys(f.clock).sort().join(",")!=="bytes,placements,policies,proofs,records,signers"||!f.storage||Object.keys(f.storage).sort().join(",")!=="acts,bytes"||[...Object.values(f.clock),...Object.values(f.storage)].some(e=>!Number.isSafeInteger(e)||e<1))&&i("missing inherited resource authority"),t.history.length+t.legacyOriginals.length>s.lines&&i("input line budget");let K=0;for(const e of[...t.history,...t.legacyOriginals])(typeof e!="string"||e.length>s.bytes||(K+=Buffer.byteLength(e))>s.bytes)&&i("input byte budget");const O=new Map;for(const e of t.history){const r=h(c(e).epoch??i("history clock absent"));let a=O.get(r);if(!a){const p=t.history.filter(n=>!S(n)||h(c(n).epoch??i("history clock absent"))<=r);a=I(p,t.anchor,Q(J(p.filter(n=>H(n,"scope").startsWith("wire/"))).standing).admitted),O.set(r,a)}a.of(e).kind!=="admitted"&&i("history not authenticated at admission")}const u=J(t.history.filter(S)).standing.filter(e=>H(e,"value")!=="withdraw"),b=u.filter(e=>{const r=c(e);return r.scope===t.profileSelector&&r.measure==="id"});(b.length!==1||c(b[0]).value!==_||c(b[0]).role!=="writes"||c(b[0]).form!=="alphabet"||c(b[0]).by!==t.anchor.id)&&i("missing/ambiguous clock profile id");const j=u.filter(e=>{const r=c(e);return r.scope===t.selector&&r.measure==="text"});j.length!==1&&i("missing/ambiguous Root selector");const N=j[0],d=c(N);(d.by!==t.anchor.id||d.role!=="writes"||d.form!=="alphabet"||d.value!=="lock"||!L(N,t.anchor.publicKey,t.algorithms))&&i("selector is not Root signed"),(!d.about||d.about.length>s.bytes)&&i("missing selector body");let o;try{o=JSON.parse(d.about)}catch{return i("selector JSON")}(!o||Object.keys(o).sort().join(",")!=="budget,digestAlgorithm,initial,namespace,profile,receiptScope,receiptSigner,regionFamily,storageBudget"||o.profile!==_||o.digestAlgorithm!=="sha256"||!m(o.namespace)||!m(o.regionFamily)||!m(o.receiptSigner)||!m(o.receiptScope)||!Array.isArray(o.initial)||!o.initial.length||o.initial.length>s.places)&&i("unsupported selector shape"),JSON.stringify(o)!==d.about&&i("noncanonical selector JSON"),(!o.budget||Object.keys(o.budget).sort().join(",")!=="bytes,placements,policies,proofs,records,signers"||Object.values(o.budget).some(e=>!Number.isSafeInteger(e)||e<1)||!o.storageBudget||Object.keys(o.storageBudget).sort().join(",")!=="acts,bytes"||Object.values(o.storageBudget).some(e=>!Number.isSafeInteger(e)||e<1))&&i("missing selected resources");for(const e of["bytes","records","placements","policies","proofs","signers"])o.budget[e]>f.clock[e]&&i("clock resource exceeds inherited "+e);for(const e of["acts","bytes"])o.storageBudget[e]>f.storage[e]&&i("storage resource exceeds inherited "+e);(o.budget.bytes>s.bytes||o.storageBudget.bytes>s.bytes||o.budget.records>s.lines||o.budget.placements>s.places)&&i("selected resources exceed input authority");const A=q(u.map(c),Number.MAX_SAFE_INTEGER);(!A||!A.digests.has(o.digestAlgorithm))&&i("digest algorithm not declared");const X=I(t.history,t.anchor,t.algorithms);(!t.history.includes(t.authorityCheckpoint)||!S(t.authorityCheckpoint))&&i("missing authenticated Root authority checkpoint");const M=h(c(t.authorityCheckpoint).epoch??i("Root authority clock absent"));O.get(M)?.of(t.authorityCheckpoint).kind!=="admitted"&&i("Root checkpoint not admitted at original epoch");const w=h(c(t.authorityCheckpoint).epoch??i("Root authority clock absent"));t.history.filter(S).some(e=>h(c(e).epoch??i("history clock absent"))>w)&&i("authority checkpoint precedes Root configuration");const C=y(t.history.join(`
2
+ `)+`
3
+ `),E=y(u.join(`
4
+ `)+`
5
+ `),R=[...new Set(u.map(y))].sort();R.length>o.budget.policies&&i("actual dependency budget");const B={namespace:o.namespace,snapshot:y(JSON.stringify([C,E,String(w)])),epoch:String(w),prefix:C,head:E,policies:R},k=o.initial.map(e=>{(!e||!e.receiver||!e.origin||!m(e.receiver.identity)||!m(e.origin.prefix)||!m(e.place))&&i("unknown initial namespace");const r=e.place.split("/");return e.place!=="."&&(r.length<2||r.at(-1)!=="TARGET.bound"||r.some(a=>a===""||a==="."||a===".."))&&i("unknown initial namespace"),h(e.receiver.epoch),h(e.origin.epoch),{place:e.place,identity:e.receiver.identity,epoch:e.receiver.epoch}});new Set(k.map(e=>e.place)).size!==k.length&&i("duplicate namespace");const W=new Set(t.legacyOriginals.map(e=>y(F(c(e)))));let x=[];const T={budget:o.budget,root:B,signers:X.admitted,places:k.map(e=>e.place),regionFamily:o.regionFamily,receiptSigner:o.receiptSigner,receiptScope:o.receiptScope,digest:y,verifiesRootContext:l(e=>JSON.stringify(e)===JSON.stringify(B),"verifiesRootContext"),verifiesNamespaceAdmission:l(e=>{if(e===".")return!0;const r=e.split("/");if(r.length<2||r.pop()!=="TARGET.bound"||r.some(g=>g===""||g==="."||g===".."))return!1;const a=r.join("/"),p=u.filter(g=>c(g).scope===o.regionFamily+"/"+a);if(p.length!==1)return!1;const n=c(p[0]);return n.role==="writes"&&n.form==="alphabet"&&n.measure==="coordinates"&&n.value===a+"/**"},"verifiesNamespaceAdmission"),verifiesNewLocalPrefix:l((e,r,a,p)=>{const n=x.find(v=>v.place===e),g=o.initial.find(v=>v.place===e);return!n||!g||p.some(v=>W.has(y(F(c(v)))))?!1:n.identity===g.receiver.identity?r===g.origin.prefix&&a===g.origin.epoch:r===n.identity&&h(a)===h(n.epoch)+1},"verifiesNewLocalPrefix"),verifiesOriginal:l((e,r)=>L(e,r.publicKey,t.algorithms),"verifiesOriginal"),verifiesProof:l((e,r,a)=>Y(e,a.publicKey,r,t.algorithms),"verifiesProof")};x=t.authenticatedReceiverHeads??P(t.store,k,{contract:T,historical:t.historical},o.storageBudget);const z={contract:T,initialHeads:k,current:l(()=>{const e=Z({...t,...t.readCurrent(),authenticatedReceiverHeads:void 0});return{root:e.trust.contract.root,heads:P(t.store,e.trust.initialHeads,e.trust,e.selection.storageBudget)}},"current"),historical:t.historical};return{selection:o,trust:z}}l(Z,"hostClockSelection");export{Z as hostClockSelection};
@@ -1,57 +1,2 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { requireEffects } from "../read-only.js";
4
- import { underTheLock } from "../../land/act.js";
5
- import { nativePublicationStorage, publishBundle } from "./publication.js";
6
- /** Directory publication makes the pair visible together; there is no later ledger append that can expose half. */
7
- export const nativeIngressStorage = nativePublicationStorage;
8
- const directory = (store) => join(store, 'ingress');
9
- const nameOf = (identity) => {
10
- if (!identity || identity.includes('\0'))
11
- throw Error('REFUSE·ingress missing import identity');
12
- return 'committed-' + encodeURIComponent(identity);
13
- };
14
- const read = (at) => ({ evidence: readFileSync(join(at, 'evidence.bound'), 'utf8'), receipt: readFileSync(join(at, 'receipt.bound'), 'utf8') });
15
- const measured = (kind, bundle) => ({ kind, ...bundle, evidenceBytes: Buffer.byteLength(bundle.evidence), receiptBytes: Buffer.byteLength(bundle.receipt) });
16
- /** Native signed receipt lines only. Foreign bytes are never added to the local ledger or epoch allocator. */
17
- export function ingressReceipts(store) {
18
- const root = directory(store);
19
- if (!existsSync(root))
20
- return [];
21
- return readdirSync(root).filter(name => name.startsWith('committed-')).sort().flatMap(name => read(join(root, name)).receipt.split('\n').filter(Boolean));
22
- }
23
- /** Private staging directories are invisible to readers and may be discarded after host recovery. */
24
- export function ingressEvidence(store, identity) {
25
- const at = join(directory(store), nameOf(identity));
26
- return existsSync(at) ? read(at) : undefined;
27
- }
28
- export function ingressBundles(store) {
29
- const root = directory(store);
30
- if (!existsSync(root))
31
- return [];
32
- return readdirSync(root).filter(name => name.startsWith('committed-')).sort().map(name => read(join(root, name)));
33
- }
34
- /** Verification and signing complete before staging. Replay performs no signer invocation or persistent write. */
35
- export async function commitIngress(store, identity, prepare, verify, storage = nativeIngressStorage) {
36
- requireEffects('foreign evidence ingress');
37
- return underTheLock(store, 'ingress', async () => {
38
- const root = directory(store), at = join(root, nameOf(identity));
39
- if (existsSync(at)) {
40
- const prior = read(at);
41
- if (verify(prior) !== true)
42
- throw Error('REFUSE·ingress committed bytes do not verify');
43
- return measured('once', prior);
44
- }
45
- const bundle = await prepare(ingressReceipts(store));
46
- if (!bundle.evidence || !bundle.receipt || verify(bundle) !== true)
47
- throw Error('REFUSE·ingress evidence and receipt do not verify');
48
- publishBundle(at, { 'evidence.bound': bundle.evidence, 'receipt.bound': bundle.receipt }, storage);
49
- return measured('landed', bundle);
50
- });
51
- }
52
- /** Costs distinguish delivered bytes from newly committed bytes; no count is called information or freedom. */
53
- export function ingressCost(result, deliveredBytes, protocolBytes) {
54
- if (!Number.isSafeInteger(deliveredBytes) || deliveredBytes < 0 || !Number.isSafeInteger(protocolBytes) || protocolBytes < 0)
55
- throw Error('REFUSE·ingress invalid exchange byte measurement');
56
- return `EXCHANGE ${deliveredBytes} payload bytes · ${protocolBytes} protocol bytes · ${result.kind === 'once' ? 0 : result.evidenceBytes} new evidence bytes · ${result.kind === 'once' ? 0 : result.receiptBytes} new receipt bytes`;
57
- }
1
+ var v=Object.defineProperty;var n=(e,r)=>v(e,"name",{value:r,configurable:!0});import{existsSync as s,readFileSync as m,readdirSync as p}from"node:fs";import{join as i}from"node:path";import{requireEffects as h}from"../read-only.js";import{underTheLock as S}from"../../land/act.js";import{nativePublicationStorage as l,publishBundle as x}from"./publication.js";const w=l,c=n(e=>i(e,"ingress"),"directory"),g=n(e=>{if(!e||e.includes("\0"))throw Error("REFUSE\xB7ingress missing import identity");return"committed-"+encodeURIComponent(e)},"nameOf"),d=n(e=>({evidence:m(i(e,"evidence.bound"),"utf8"),receipt:m(i(e,"receipt.bound"),"utf8")}),"read"),E=n((e,r)=>({kind:e,...r,evidenceBytes:Buffer.byteLength(r.evidence),receiptBytes:Buffer.byteLength(r.receipt)}),"measured");function R(e){const r=c(e);return s(r)?p(r).filter(t=>t.startsWith("committed-")).sort().flatMap(t=>d(i(r,t)).receipt.split(`
2
+ `).filter(Boolean)):[]}n(R,"ingressReceipts");function C(e,r){const t=i(c(e),g(r));return s(t)?d(t):void 0}n(C,"ingressEvidence");function L(e){const r=c(e);return s(r)?p(r).filter(t=>t.startsWith("committed-")).sort().map(t=>d(i(r,t))):[]}n(L,"ingressBundles");async function N(e,r,t,u,b=w){return h("foreign evidence ingress"),S(e,"ingress",async()=>{const y=c(e),f=i(y,g(r));if(s(f)){const a=d(f);if(u(a)!==!0)throw Error("REFUSE\xB7ingress committed bytes do not verify");return E("once",a)}const o=await t(R(e));if(!o.evidence||!o.receipt||u(o)!==!0)throw Error("REFUSE\xB7ingress evidence and receipt do not verify");return x(f,{"evidence.bound":o.evidence,"receipt.bound":o.receipt},b),E("landed",o)})}n(N,"commitIngress");function W(e,r,t){if(!Number.isSafeInteger(r)||r<0||!Number.isSafeInteger(t)||t<0)throw Error("REFUSE\xB7ingress invalid exchange byte measurement");return`EXCHANGE ${r} payload bytes \xB7 ${t} protocol bytes \xB7 ${e.kind==="once"?0:e.evidenceBytes} new evidence bytes \xB7 ${e.kind==="once"?0:e.receiptBytes} new receipt bytes`}n(W,"ingressCost");export{N as commitIngress,L as ingressBundles,W as ingressCost,C as ingressEvidence,R as ingressReceipts,w as nativeIngressStorage};
@@ -1,183 +1,5 @@
1
- import { hashText } from "../hash.js";
2
- import { ActCommitUnknown } from "../commit-result.js";
3
- import { assertHostNotCancelled } from "../host-controls.js";
4
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
5
- import { join } from 'node:path';
6
- import { createHash } from 'node:crypto';
7
- import { requireEffects } from "../read-only.js";
8
- import { underTheRegions } from "../../land/act.js";
9
- import { publishBundle, nativePublicationStorage } from "./publication.js";
10
- import { actIdentity, parse, canonical } from '@lapxo/topos/wire';
11
- import { fullDigest } from "../digest.js";
12
- const atOf = (store, identity) => {
13
- if (!identity || identity.includes('\0'))
14
- throw Error('REFUSE·act missing identity');
15
- return join(store, 'ledger', 'acts', 'committed-' + encodeURIComponent(identity));
16
- };
17
- const read = (at) => {
18
- try {
19
- const placements = readdirSync(at).filter(name => name.startsWith('place-') && name.endsWith('.bound')).map(name => ({
20
- place: decodeURIComponent(name.slice(6, -6)), records: readFileSync(join(at, name), 'utf8'),
21
- }));
22
- return {
23
- records: readFileSync(join(at, 'records.bound'), 'utf8'),
24
- receipt: readFileSync(join(at, 'receipt.bound'), 'utf8'),
25
- ...(placements.length ? { placements } : {}),
26
- };
27
- }
28
- catch (error) {
29
- throw Error(`REFUSE·act committed result unreadable · ${error.code ?? 'read failed'}`);
30
- }
31
- };
32
- export const actLines = (bytes) => {
33
- if (!bytes.endsWith('\n'))
34
- throw Error('REFUSE·act truncated committed lines');
35
- return bytes.slice(0, -1).split('\n');
36
- };
37
- /** Journal integrity is not authority. Signature/coverage checks remain the
38
- * same admission boundary; the hash algorithm here is the stored seal's named
39
- * algorithm, not a new selection of the place's wire.
40
- */
41
- export function intactLocalAct(identity, bundle) {
42
- if (!bundle.receipt.endsWith('\n') || bundle.receipt.slice(0, -1).includes('\n'))
43
- return false;
44
- const receipt = parse(bundle.receipt.slice(0, -1));
45
- if (receipt.kind !== 'fact' || !bundle.placements?.length)
46
- return false;
47
- const f = receipt.value.fields;
48
- if (canonical(f) !== bundle.receipt.slice(0, -1) || !/^(0|[1-9][0-9]*)$/.test(f['epoch'] ?? ''))
49
- return false;
50
- if (f['value'] !== identity || f['role'] !== 'writes' || f['form'] !== 'alphabet' || f['measure'] !== 'digest')
51
- return false;
52
- return actIdentity(actLines(bundle.records), { scope: f['scope'] ?? '', context: f['at'] ?? '',
53
- localEpoch: Number(f['epoch']), digest: bytes => fullDigest(bytes, identity.slice(0, identity.indexOf(':'))),
54
- placements: bundle.placements.map(p => ({ place: p.place, records: actLines(p.records) })),
55
- }) === identity;
56
- }
57
- /** One last integrity result only. Every call rereads all exact current bytes;
58
- * signatures, coverage and current authority are never retained here. */
59
- let lastIntactInventory;
60
- /** Internal integrity key only, not an act identity or a wire profile. */
61
- export function committedInventoryFingerprint(rows) {
62
- const hash = createHash('sha256');
63
- const text = hashText.bind(undefined, hash);
64
- text('committed-integrity-inventory');
65
- text(String(rows.length));
66
- for (const { identity, bundle } of rows) {
67
- text(identity);
68
- text(bundle.records);
69
- text(bundle.receipt);
70
- if (bundle.placements === undefined) {
71
- text('absent');
72
- continue;
73
- }
74
- text('present');
75
- text(String(bundle.placements.length));
76
- for (const placement of bundle.placements) {
77
- text(placement.place);
78
- text(placement.records);
79
- }
80
- }
81
- return hash.digest('hex');
82
- }
83
- /** Committed segments are part of this ledger, not a second authority source. */
84
- export function committedLocalActs(store) {
85
- const observed = observationAt(store);
86
- if (observed)
87
- return observed.rows;
88
- return readCommittedLocalActs(store);
89
- }
90
- let committedObservation;
91
- function observationAt(store) { for (let one = committedObservation; one; one = one.parent)
92
- if (one.store === store)
93
- return one; return undefined; }
94
- /** Fixed host observation only: one synchronous, coherent committed inventory.
95
- * It supplies no authority, verifier or async lifetime. Each outer invocation
96
- * rereads exact bodies before entering; current authorization still runs inside.
97
- */
98
- export function withCommittedLocalActObservation(store, body) {
99
- const prior = committedObservation, existing = observationAt(store);
100
- const rows = existing?.rows ?? Object.freeze(readCommittedLocalActs(store).map(row => Object.freeze({ identity: row.identity, bundle: Object.freeze({ ...row.bundle, ...(row.bundle.placements ? { placements: Object.freeze(row.bundle.placements.map(p => Object.freeze({ ...p }))) } : {}) }) })));
101
- committedObservation = { store, rows, parent: prior };
102
- try {
103
- const result = body();
104
- if (result !== null && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function')
105
- throw Error('REFUSE·act committed observation must be synchronous');
106
- return result;
107
- }
108
- finally {
109
- committedObservation = prior;
110
- }
111
- }
112
- function readCommittedLocalActs(store) {
113
- const root = join(store, 'ledger', 'acts');
114
- if (!existsSync(root))
115
- return [];
116
- const rows = readdirSync(root).filter(name => name.startsWith('committed-')).map(name => ({
117
- identity: decodeURIComponent(name.slice(10)), bundle: read(join(root, name)),
118
- }));
119
- // Ordered tuple framing commits every record, receipt and placement. No path,
120
- // mtime, authority snapshot or caller-supplied seal substitutes for bytes.
121
- const fingerprint = committedInventoryFingerprint(rows);
122
- if (fingerprint !== lastIntactInventory) {
123
- for (const { identity, bundle } of rows)
124
- if (!intactLocalAct(identity, bundle))
125
- throw Error('REFUSE·act committed journal seal does not verify');
126
- lastIntactInventory = fingerprint;
127
- }
128
- return rows.sort((a, b) => {
129
- const epoch = (one) => { const p = parse(one.receipt.trim()); return p.kind === 'fact' ? Number(p.value.fields['epoch']) : 0; };
130
- return epoch(a.bundle) - epoch(b.bundle);
131
- });
132
- }
133
- /** A public result is available only as a verified committed pair.
134
- * No writer-tail guess, newest-result selection or implicit authority.
135
- */
136
- export function localActResult(store, identity, verify) {
137
- const at = atOf(store, identity);
138
- const observed = observationAt(store);
139
- if (observed) {
140
- const bundle = observed.rows.find(row => row.identity === identity)?.bundle;
141
- if (!bundle)
142
- return undefined;
143
- if (verify(identity, bundle) !== true)
144
- throw Error('REFUSE·act committed result does not verify');
145
- return bundle;
146
- }
147
- if (!existsSync(at))
148
- return undefined;
149
- const bundle = read(at);
150
- if (verify(identity, bundle) !== true)
151
- throw Error('REFUSE·act committed result does not verify');
152
- return bundle;
153
- }
154
- /** One publication point for records and their native result. Re-delivery
155
- * reads the original pair without preparation, signing or a new local epoch.
156
- * The caller must also integrate this boundary into admission-history readers;
157
- * this storage port alone does not activate a grammar or land authority.
158
- */
159
- export async function commitLocalAct(store, identity, regions, prepare, verify, storage = nativePublicationStorage, signal) {
160
- requireEffects('local act commitment');
161
- assertHostNotCancelled(signal);
162
- return underTheRegions(store, regions, 'land', async () => {
163
- assertHostNotCancelled(signal);
164
- const prior = localActResult(store, identity, verify);
165
- if (prior)
166
- return { kind: 'once', ...prior };
167
- const bundle = await prepare();
168
- assertHostNotCancelled(signal);
169
- if (!bundle.records || !bundle.receipt || verify(identity, bundle) !== true)
170
- throw Error('REFUSE·act prepared result does not verify');
171
- const files = { 'records.bound': bundle.records, 'receipt.bound': bundle.receipt };
172
- for (const p of bundle.placements ?? [])
173
- files['place-' + encodeURIComponent(p.place) + '.bound'] = p.records;
174
- assertHostNotCancelled(signal);
175
- try {
176
- publishBundle(atOf(store, identity), files, storage);
177
- }
178
- catch (error) {
179
- throw new ActCommitUnknown(identity, error);
180
- }
181
- return { kind: 'landed', ...bundle };
182
- });
183
- }
1
+ var U=Object.defineProperty;var i=(t,e)=>U(t,"name",{value:e,configurable:!0});import{hashText as F}from"../hash.js";import{ActCommitUnknown as I}from"../commit-result.js";import{assertHostNotCancelled as u}from"../host-controls.js";import{existsSync as E,readFileSync as m,readdirSync as y}from"node:fs";import{join as d}from"node:path";import{createHash as O}from"node:crypto";import{requireEffects as j}from"../read-only.js";import{underTheRegions as A}from"../../land/act.js";import{publishBundle as C,nativePublicationStorage as L}from"./publication.js";import{library14_actIdentity as k,library14_parse as g,library14_canonical as z}from"../../vendor/runtime.js";import{fullDigest as W}from"../digest.js";const v=i((t,e)=>{if(!e||e.includes("\0"))throw Error("REFUSE\xB7act missing identity");return d(t,"ledger","acts","committed-"+encodeURIComponent(e))},"atOf"),w=i(t=>{try{const e=y(t).filter(r=>r.startsWith("place-")&&r.endsWith(".bound")).map(r=>({place:decodeURIComponent(r.slice(6,-6)),records:m(d(t,r),"utf8")}));return{records:m(d(t,"records.bound"),"utf8"),receipt:m(d(t,"receipt.bound"),"utf8"),...e.length?{placements:e}:{}}}catch(e){throw Error(`REFUSE\xB7act committed result unreadable \xB7 ${e.code??"read failed"}`)}},"read"),x=i(t=>{if(!t.endsWith(`
2
+ `))throw Error("REFUSE\xB7act truncated committed lines");return t.slice(0,-1).split(`
3
+ `)},"actLines");function N(t,e){if(!e.receipt.endsWith(`
4
+ `)||e.receipt.slice(0,-1).includes(`
5
+ `))return!1;const r=g(e.receipt.slice(0,-1));if(r.kind!=="fact"||!e.placements?.length)return!1;const c=r.value.fields;return z(c)!==e.receipt.slice(0,-1)||!/^(0|[1-9][0-9]*)$/.test(c.epoch??"")||c.value!==t||c.role!=="writes"||c.form!=="alphabet"||c.measure!=="digest"?!1:k(x(e.records),{scope:c.scope??"",context:c.at??"",localEpoch:Number(c.epoch),digest:i(o=>W(o,t.slice(0,t.indexOf(":"))),"digest"),placements:e.placements.map(o=>({place:o.place,records:x(o.records)}))})===t}i(N,"intactLocalAct");let R;function _(t){const e=O("sha256"),r=F.bind(void 0,e);r("committed-integrity-inventory"),r(String(t.length));for(const{identity:c,bundle:o}of t){if(r(c),r(o.records),r(o.receipt),o.placements===void 0){r("absent");continue}r("present"),r(String(o.placements.length));for(const n of o.placements)r(n.place),r(n.records)}return e.digest("hex")}i(_,"committedInventoryFingerprint");function X(t){const e=h(t);return e?e.rows:S(t)}i(X,"committedLocalActs");let p;function h(t){for(let e=p;e;e=e.parent)if(e.store===t)return e}i(h,"observationAt");function Y(t,e){const r=p,o=h(t)?.rows??Object.freeze(S(t).map(n=>Object.freeze({identity:n.identity,bundle:Object.freeze({...n.bundle,...n.bundle.placements?{placements:Object.freeze(n.bundle.placements.map(s=>Object.freeze({...s})))}:{}})})));p={store:t,rows:o,parent:r};try{const n=e();if(n!==null&&(typeof n=="object"||typeof n=="function")&&typeof n.then=="function")throw Error("REFUSE\xB7act committed observation must be synchronous");return n}finally{p=r}}i(Y,"withCommittedLocalActObservation");function S(t){const e=d(t,"ledger","acts");if(!E(e))return[];const r=y(e).filter(o=>o.startsWith("committed-")).map(o=>({identity:decodeURIComponent(o.slice(10)),bundle:w(d(e,o))})),c=_(r);if(c!==R){for(const{identity:o,bundle:n}of r)if(!N(o,n))throw Error("REFUSE\xB7act committed journal seal does not verify");R=c}return r.sort((o,n)=>{const s=i(l=>{const a=g(l.receipt.trim());return a.kind==="fact"?Number(a.value.fields.epoch):0},"epoch");return s(o.bundle)-s(n.bundle)})}i(S,"readCommittedLocalActs");function H(t,e,r){const c=v(t,e),o=h(t);if(o){const s=o.rows.find(l=>l.identity===e)?.bundle;if(!s)return;if(r(e,s)!==!0)throw Error("REFUSE\xB7act committed result does not verify");return s}if(!E(c))return;const n=w(c);if(r(e,n)!==!0)throw Error("REFUSE\xB7act committed result does not verify");return n}i(H,"localActResult");async function Z(t,e,r,c,o,n=L,s){return j("local act commitment"),u(s),A(t,r,"land",async()=>{u(s);const l=H(t,e,o);if(l)return{kind:"once",...l};const a=await c();if(u(s),!a.records||!a.receipt||o(e,a)!==!0)throw Error("REFUSE\xB7act prepared result does not verify");const b={"records.bound":a.records,"receipt.bound":a.receipt};for(const f of a.placements??[])b["place-"+encodeURIComponent(f.place)+".bound"]=f.records;u(s);try{C(v(t,e),b,n)}catch(f){throw new I(e,f)}return{kind:"landed",...a}})}i(Z,"commitLocalAct");export{x as actLines,Z as commitLocalAct,_ as committedInventoryFingerprint,X as committedLocalActs,N as intactLocalAct,H as localActResult,Y as withCommittedLocalActObservation};
@@ -1,134 +1 @@
1
- import { existsSync, readdirSync, statSync, openSync, fstatSync, readSync, closeSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { readPlaceActContext, placeActReceiptsOf } from '@lapxo/topos/core';
4
- import { transactPlaceAct } from "../place-act-transaction.js";
5
- import { canonicalActStore, underAuthorityRegions, underTheRegions, underRootProjection } from "../../land/act.js";
6
- import { requireEffects } from "../read-only.js";
7
- import { receiverClock } from "../host-controls.js";
8
- import { publishBundle, nativePublicationStorage } from "./publication.js";
9
- const fail = (why) => { throw Error('REFUSE·place act ' + why); };
10
- const budget = (b) => { if (!b || !Number.isSafeInteger(b.acts) || b.acts < 1 || !Number.isSafeInteger(b.bytes) || b.bytes < 1)
11
- fail('missing storage budget'); };
12
- const base = (store) => join(store, 'ledger', 'place-acts');
13
- const at = (store, id) => { if (!id || id.includes('\0'))
14
- fail('missing identity'); return join(base(store), 'committed-' + encodeURIComponent(id)); };
15
- function storedInventory(store, b) {
16
- budget(b);
17
- if (!existsSync(base(store)))
18
- return { names: [], bytes: 0 };
19
- const names = readdirSync(base(store)).filter(n => n.startsWith('committed-'));
20
- if (names.length > b.acts)
21
- fail('stored act budget');
22
- let bytes = 0;
23
- for (const name of names)
24
- for (const member of ['context.json', 'receipts.json', 'originals.json']) {
25
- const stat = statSync(join(base(store), name, member));
26
- if (!stat.isFile() || (bytes += stat.size) > b.bytes)
27
- fail('stored aggregate byte budget');
28
- }
29
- return { names, bytes };
30
- }
31
- function readBundle(path, b) {
32
- budget(b);
33
- let bytes = 0;
34
- const read = (name) => {
35
- const fd = openSync(join(path, name), 'r');
36
- try {
37
- const size = fstatSync(fd);
38
- if (!size.isFile() || size.size > b.bytes - bytes)
39
- fail('stored byte budget');
40
- const data = Buffer.alloc(size.size);
41
- let read = 0;
42
- while (read < data.length) {
43
- const count = readSync(fd, data, read, data.length - read, null);
44
- if (!count)
45
- fail('stored member changed while reading');
46
- read += count;
47
- }
48
- if (readSync(fd, Buffer.alloc(1), 0, 1, null) !== 0)
49
- fail('stored member changed while reading');
50
- bytes += read;
51
- return new TextDecoder('utf-8', { fatal: true }).decode(data);
52
- }
53
- finally {
54
- closeSync(fd);
55
- }
56
- };
57
- try {
58
- const context = read('context.json'), receipts = JSON.parse(read('receipts.json')), originals = JSON.parse(read('originals.json'));
59
- return { context, receipts, originals };
60
- }
61
- catch (e) {
62
- if (e instanceof Error && e.message.startsWith('REFUSE·'))
63
- throw e;
64
- return fail('committed bundle unreadable');
65
- }
66
- }
67
- function authenticated(bundle, id, contract) {
68
- const result = placeActReceiptsOf(bundle.context, bundle.receipts, contract), decoded = readPlaceActContext(bundle.context, contract.budget);
69
- if (result.identity !== id || JSON.stringify(bundle.originals) !== JSON.stringify(decoded.places.map(p => p.records)))
70
- fail('stored original/context identity mismatch');
71
- return decoded;
72
- }
73
- /** Historical result reads never produce a current authorization permit. */
74
- export function placeActResult(store, id, trust, limits) {
75
- const path = at(store, id);
76
- if (!existsSync(path))
77
- return undefined;
78
- const bundle = readBundle(path, limits);
79
- authenticated(bundle, id, trust.historical(bundle.context));
80
- return bundle;
81
- }
82
- /** Each receiver chain advances independently. Initial heads are explicit,
83
- * authenticated host inputs, not inferred zero or legacy global epochs. */
84
- export function placeActHeads(store, initial, trust, limits) {
85
- budget(limits);
86
- if (!initial.length || new Set(initial.map(h => h.place)).size !== initial.length)
87
- fail('missing/ambiguous initial heads');
88
- const heads = new Map(initial.map(h => { receiverClock(h.epoch, fail); if (!h.identity)
89
- fail('missing initial head'); return [h.place, { ...h }]; }));
90
- if (!existsSync(base(store)))
91
- return [...heads.values()];
92
- const { names } = storedInventory(store, limits);
93
- const pending = names.map(name => { const id = decodeURIComponent(name.slice(10)), bundle = readBundle(join(base(store), name), limits); const context = authenticated(bundle, id, trust.historical(bundle.context)); if (context.root.namespace !== trust.contract.root.namespace)
94
- fail('stored clock namespace mismatch'); return { id, context }; });
95
- while (pending.length) {
96
- const next = pending.findIndex(a => a.context.places.every(p => heads.get(p.place)?.identity === p.previous));
97
- if (next < 0)
98
- fail('receiver chain fork or missing predecessor');
99
- const act = pending.splice(next, 1)[0];
100
- for (const p of act.context.places) {
101
- const prior = heads.get(p.place);
102
- const epoch = receiverClock(prior.epoch, fail) + 1;
103
- if (!Number.isSafeInteger(epoch) || receiverClock(p.epoch, fail) !== epoch)
104
- fail('receiver chain clock mismatch');
105
- heads.set(p.place, { place: p.place, identity: act.id, epoch: p.epoch });
106
- }
107
- }
108
- return [...heads.values()];
109
- }
110
- /** Context, exact original bytes and complete signed receipts have one visibility
111
- * point. Real Root guard exclusion spans final authority/head comparison and
112
- * publication; this does not activate a CLI profile or reinterpret local-act@1. */
113
- /** Native persistence adapter. The transaction below is also the CLI path. */
114
- export function nativePlaceActPersistence(store, storage = nativePublicationStorage) {
115
- store = canonicalActStore(store);
116
- return {
117
- exclusive: (regions, run) => { const enter = regions.includes('') ? underTheRegions : underAuthorityRegions; return enter(store, regions, 'place act', () => underRootProjection(store, 'place act publication', run)); },
118
- result: (identity, trust, limits) => placeActResult(store, identity, trust, limits),
119
- inventory: limits => storedInventory(store, limits),
120
- heads: (trust, limits) => placeActHeads(store, trust.initialHeads, trust, limits),
121
- publish: (identity, files) => publishBundle(at(store, identity), files, storage),
122
- };
123
- }
124
- export async function commitPlaceAct(store, encoded, receipts, trust, limits, storage = nativePublicationStorage) {
125
- requireEffects('place act commitment');
126
- return transactPlaceAct(encoded, receipts, trust, limits, nativePlaceActPersistence(store, storage));
127
- }
128
- /** Enumerates only committed, historically authenticated carriers. Namespace
129
- * projection is a caller's separate pure operation, never current permission. */
130
- export function committedPlaceActResults(store, trust, limits) {
131
- const { names } = storedInventory(store, limits);
132
- return names.map(name => { const identity = decodeURIComponent(name.slice(10)), bundle = placeActResult(store, identity, trust, limits); if (!bundle)
133
- fail('committed carrier vanished'); return { identity, bundle: bundle }; });
134
- }
1
+ var j=Object.defineProperty;var i=(e,c)=>j(e,"name",{value:c,configurable:!0});import{existsSync as g,readdirSync as I,statSync as E,openSync as N,fstatSync as C,readSync as S,closeSync as O}from"node:fs";import{join as f}from"node:path";import{library6_readPlaceActContext as z,library6_placeActReceiptsOf as U}from"../../vendor/runtime.js";import{transactPlaceAct as k}from"../place-act-transaction.js";import{canonicalActStore as B,underAuthorityRegions as F,underTheRegions as J,underRootProjection as H}from"../../land/act.js";import{requireEffects as T}from"../read-only.js";import{receiverClock as h}from"../host-controls.js";import{publishBundle as W,nativePublicationStorage as v}from"./publication.js";const s=i(e=>{throw Error("REFUSE\xB7place act "+e)},"fail"),y=i(e=>{(!e||!Number.isSafeInteger(e.acts)||e.acts<1||!Number.isSafeInteger(e.bytes)||e.bytes<1)&&s("missing storage budget")},"budget"),m=i(e=>f(e,"ledger","place-acts"),"base"),A=i((e,c)=>((!c||c.includes("\0"))&&s("missing identity"),f(m(e),"committed-"+encodeURIComponent(c))),"at");function b(e,c){if(y(c),!g(m(e)))return{names:[],bytes:0};const t=I(m(e)).filter(n=>n.startsWith("committed-"));t.length>c.acts&&s("stored act budget");let o=0;for(const n of t)for(const r of["context.json","receipts.json","originals.json"]){const l=E(f(m(e),n,r));(!l.isFile()||(o+=l.size)>c.bytes)&&s("stored aggregate byte budget")}return{names:t,bytes:o}}i(b,"storedInventory");function R(e,c){y(c);let t=0;const o=i(n=>{const r=N(f(e,n),"r");try{const l=C(r);(!l.isFile()||l.size>c.bytes-t)&&s("stored byte budget");const a=Buffer.alloc(l.size);let p=0;for(;p<a.length;){const d=S(r,a,p,a.length-p,null);d||s("stored member changed while reading"),p+=d}return S(r,Buffer.alloc(1),0,1,null)!==0&&s("stored member changed while reading"),t+=p,new TextDecoder("utf-8",{fatal:!0}).decode(a)}finally{O(r)}},"read");try{const n=o("context.json"),r=JSON.parse(o("receipts.json")),l=JSON.parse(o("originals.json"));return{context:n,receipts:r,originals:l}}catch(n){if(n instanceof Error&&n.message.startsWith("REFUSE\xB7"))throw n;return s("committed bundle unreadable")}}i(R,"readBundle");function w(e,c,t){const o=U(e.context,e.receipts,t),n=z(e.context,t.budget);return(o.identity!==c||JSON.stringify(e.originals)!==JSON.stringify(n.places.map(r=>r.records)))&&s("stored original/context identity mismatch"),n}i(w,"authenticated");function P(e,c,t,o){const n=A(e,c);if(!g(n))return;const r=R(n,o);return w(r,c,t.historical(r.context)),r}i(P,"placeActResult");function _(e,c,t,o){y(o),(!c.length||new Set(c.map(a=>a.place)).size!==c.length)&&s("missing/ambiguous initial heads");const n=new Map(c.map(a=>(h(a.epoch,s),a.identity||s("missing initial head"),[a.place,{...a}])));if(!g(m(e)))return[...n.values()];const{names:r}=b(e,o),l=r.map(a=>{const p=decodeURIComponent(a.slice(10)),d=R(f(m(e),a),o),u=w(d,p,t.historical(d.context));return u.root.namespace!==t.contract.root.namespace&&s("stored clock namespace mismatch"),{id:p,context:u}});for(;l.length;){const a=l.findIndex(d=>d.context.places.every(u=>n.get(u.place)?.identity===u.previous));a<0&&s("receiver chain fork or missing predecessor");const p=l.splice(a,1)[0];for(const d of p.context.places){const u=n.get(d.place),x=h(u.epoch,s)+1;(!Number.isSafeInteger(x)||h(d.epoch,s)!==x)&&s("receiver chain clock mismatch"),n.set(d.place,{place:d.place,identity:p.id,epoch:d.epoch})}}return[...n.values()]}i(_,"placeActHeads");function q(e,c=v){return e=B(e),{exclusive:i((t,o)=>(t.includes("")?J:F)(e,t,"place act",()=>H(e,"place act publication",o)),"exclusive"),result:i((t,o,n)=>P(e,t,o,n),"result"),inventory:i(t=>b(e,t),"inventory"),heads:i((t,o)=>_(e,t.initialHeads,t,o),"heads"),publish:i((t,o)=>W(A(e,t),o,c),"publish")}}i(q,"nativePlaceActPersistence");async function Z(e,c,t,o,n,r=v){return T("place act commitment"),k(c,t,o,n,q(e,r))}i(Z,"commitPlaceAct");function $(e,c,t){const{names:o}=b(e,t);return o.map(n=>{const r=decodeURIComponent(n.slice(10)),l=P(e,r,c,t);return l||s("committed carrier vanished"),{identity:r,bundle:l}})}i($,"committedPlaceActResults");export{Z as commitPlaceAct,$ as committedPlaceActResults,q as nativePlaceActPersistence,_ as placeActHeads,P as placeActResult};
@@ -1,56 +1 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { closeSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
- import { dirname, join } from 'node:path';
4
- import { requireEffects } from "../read-only.js";
5
- const syncDirectory = (path) => {
6
- const fd = openSync(path, 'r');
7
- try {
8
- fsyncSync(fd);
9
- }
10
- finally {
11
- closeSync(fd);
12
- }
13
- };
14
- export const nativePublicationStorage = {
15
- publish(staged, committed) { renameSync(staged, committed); syncDirectory(dirname(committed)); },
16
- };
17
- /** Publish prepared bytes as one directory. No identity, grammar or authority
18
- * is inferred here. Readers address the committed name, never staging files.
19
- * A failure after rename is not evidence of rollback: the caller must retain
20
- * the uncertainty and allow a verified read of the committed name.
21
- */
22
- export function publishBundle(committed, files, storage = nativePublicationStorage) {
23
- requireEffects('atomic publication');
24
- const entries = Object.entries(files);
25
- if (!entries.length || entries.some(([name]) => !name || name === '.' || name === '..' || /[\\/\0]/.test(name))) {
26
- throw Error('REFUSE·commit invalid publication members');
27
- }
28
- const root = dirname(committed);
29
- const created = mkdirSync(root, { recursive: true });
30
- // Persist newly created directory entries up to their existing parent too.
31
- if (created !== undefined)
32
- for (let at = root;; at = dirname(at)) {
33
- syncDirectory(at);
34
- if (at === dirname(created))
35
- break;
36
- }
37
- const staged = join(root, '.stage-' + randomUUID());
38
- mkdirSync(staged, { mode: 0o700 });
39
- try {
40
- for (const [name, bytes] of entries) {
41
- const fd = openSync(join(staged, name), 'wx', 0o600);
42
- try {
43
- writeFileSync(fd, bytes);
44
- fsyncSync(fd);
45
- }
46
- finally {
47
- closeSync(fd);
48
- }
49
- }
50
- syncDirectory(staged);
51
- storage.publish(staged, committed);
52
- }
53
- finally {
54
- rmSync(staged, { recursive: true, force: true });
55
- }
56
- }
1
+ var h=Object.defineProperty;var f=(o,t)=>h(o,"name",{value:t,configurable:!0});import{randomUUID as g}from"node:crypto";import{closeSync as a,fsyncSync as u,mkdirSync as m,openSync as p,renameSync as v,rmSync as E,writeFileSync as w}from"node:fs";import{dirname as n,join as b}from"node:path";import{requireEffects as x}from"../read-only.js";const l=f(o=>{const t=p(o,"r");try{u(t)}finally{a(t)}},"syncDirectory"),U={publish(o,t){v(o,t),l(n(t))}};function B(o,t,d=U){x("atomic publication");const i=Object.entries(t);if(!i.length||i.some(([r])=>!r||r==="."||r===".."||/[\\/\0]/.test(r)))throw Error("REFUSE\xB7commit invalid publication members");const c=n(o),y=m(c,{recursive:!0});if(y!==void 0)for(let r=c;l(r),r!==n(y);r=n(r));const e=b(c,".stage-"+g());m(e,{mode:448});try{for(const[r,S]of i){const s=p(b(e,r),"wx",384);try{w(s,S),u(s)}finally{a(s)}}l(e),d.publish(e,o)}finally{E(e,{recursive:!0,force:!0})}}f(B,"publishBundle");export{U as nativePublicationStorage,B as publishBundle};