@earendil-works/chord 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -0
- package/README.md +115 -90
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/contracts/accepts.d.ts +81 -0
- package/dist/contracts/accepts.d.ts.map +1 -0
- package/dist/contracts/accepts.js +123 -0
- package/dist/contracts/accepts.js.map +1 -0
- package/dist/contracts/contract.d.ts +121 -0
- package/dist/contracts/contract.d.ts.map +1 -0
- package/dist/contracts/contract.js +50 -0
- package/dist/contracts/contract.js.map +1 -0
- package/dist/contracts/declare.d.ts +107 -0
- package/dist/contracts/declare.d.ts.map +1 -0
- package/dist/contracts/declare.js +136 -0
- package/dist/contracts/declare.js.map +1 -0
- package/dist/contracts/evolve.d.ts +92 -0
- package/dist/contracts/evolve.d.ts.map +1 -0
- package/dist/contracts/evolve.js +179 -0
- package/dist/contracts/evolve.js.map +1 -0
- package/dist/contracts/fingerprint.d.ts +16 -0
- package/dist/contracts/fingerprint.d.ts.map +1 -0
- package/dist/contracts/fingerprint.js +50 -0
- package/dist/contracts/fingerprint.js.map +1 -0
- package/dist/contracts/history.d.ts +71 -0
- package/dist/contracts/history.d.ts.map +1 -0
- package/dist/contracts/history.js +3 -0
- package/dist/contracts/history.js.map +1 -0
- package/dist/contracts/host-kind.d.ts +40 -0
- package/dist/contracts/host-kind.d.ts.map +1 -0
- package/dist/contracts/host-kind.js +37 -0
- package/dist/contracts/host-kind.js.map +1 -0
- package/dist/contracts/index.d.ts +7 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +6 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/internal.d.ts +10 -0
- package/dist/contracts/internal.d.ts.map +1 -0
- package/dist/contracts/internal.js +9 -0
- package/dist/contracts/internal.js.map +1 -0
- package/dist/contracts/names.d.ts +3 -0
- package/dist/contracts/names.d.ts.map +1 -0
- package/dist/contracts/names.js +13 -0
- package/dist/contracts/names.js.map +1 -0
- package/dist/contracts/params.d.ts +28 -0
- package/dist/contracts/params.d.ts.map +1 -0
- package/dist/contracts/params.js +50 -0
- package/dist/contracts/params.js.map +1 -0
- package/dist/contracts/schema.d.ts +102 -0
- package/dist/contracts/schema.d.ts.map +1 -0
- package/dist/contracts/schema.js +103 -0
- package/dist/contracts/schema.js.map +1 -0
- package/dist/contracts/snapshot.d.ts +16 -0
- package/dist/contracts/snapshot.d.ts.map +1 -0
- package/dist/contracts/snapshot.js +167 -0
- package/dist/contracts/snapshot.js.map +1 -0
- package/dist/data/args.d.ts +50 -0
- package/dist/data/args.d.ts.map +1 -0
- package/dist/data/args.js +83 -0
- package/dist/data/args.js.map +1 -0
- package/dist/data/errors.d.ts +80 -0
- package/dist/data/errors.d.ts.map +1 -0
- package/dist/data/errors.js +116 -0
- package/dist/data/errors.js.map +1 -0
- package/dist/data/failure.d.ts +26 -0
- package/dist/data/failure.d.ts.map +1 -0
- package/dist/data/failure.js +77 -0
- package/dist/data/failure.js.map +1 -0
- package/dist/data/index.d.ts +4 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +5 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/internal.d.ts +7 -0
- package/dist/data/internal.d.ts.map +1 -0
- package/dist/data/internal.js +8 -0
- package/dist/data/internal.js.map +1 -0
- package/dist/data/params.d.ts +20 -0
- package/dist/data/params.d.ts.map +1 -0
- package/dist/data/params.js +31 -0
- package/dist/data/params.js.map +1 -0
- package/dist/data/principal.d.ts +22 -0
- package/dist/data/principal.d.ts.map +1 -0
- package/dist/data/principal.js +49 -0
- package/dist/data/principal.js.map +1 -0
- package/dist/data/validator.d.ts +12 -0
- package/dist/data/validator.d.ts.map +1 -0
- package/dist/data/validator.js +35 -0
- package/dist/data/validator.js.map +1 -0
- package/dist/delta/apply-immutable-trusted.js +3 -4
- package/dist/delta/apply-immutable-trusted.js.map +1 -1
- package/dist/delta/diff.d.ts.map +1 -1
- package/dist/delta/diff.js +5 -3
- package/dist/delta/diff.js.map +1 -1
- package/dist/delta/index.d.ts +9 -1
- package/dist/delta/index.d.ts.map +1 -1
- package/dist/delta/index.js +15 -11
- package/dist/delta/index.js.map +1 -1
- package/dist/delta/pending.d.ts +36 -0
- package/dist/delta/pending.d.ts.map +1 -0
- package/dist/delta/pending.js +143 -0
- package/dist/delta/pending.js.map +1 -0
- package/dist/delta/tracker.d.ts +12 -0
- package/dist/delta/tracker.d.ts.map +1 -1
- package/dist/delta/tracker.js +109 -39
- package/dist/delta/tracker.js.map +1 -1
- package/dist/documents/address-source.d.ts +20 -0
- package/dist/documents/address-source.d.ts.map +1 -0
- package/dist/documents/address-source.js +44 -0
- package/dist/documents/address-source.js.map +1 -0
- package/dist/documents/definition.d.ts +84 -0
- package/dist/documents/definition.d.ts.map +1 -0
- package/dist/documents/definition.js +74 -0
- package/dist/documents/definition.js.map +1 -0
- package/dist/documents/documents.d.ts +126 -0
- package/dist/documents/documents.d.ts.map +1 -0
- package/dist/documents/documents.js +248 -0
- package/dist/documents/documents.js.map +1 -0
- package/dist/documents/fence.d.ts +9 -0
- package/dist/documents/fence.d.ts.map +1 -0
- package/dist/documents/fence.js +15 -0
- package/dist/documents/fence.js.map +1 -0
- package/dist/documents/handles.d.ts +76 -0
- package/dist/documents/handles.d.ts.map +1 -0
- package/dist/documents/handles.js +66 -0
- package/dist/documents/handles.js.map +1 -0
- package/dist/documents/index.d.ts +4 -0
- package/dist/documents/index.d.ts.map +1 -0
- package/dist/documents/index.js +3 -0
- package/dist/documents/index.js.map +1 -0
- package/dist/documents/internal.d.ts +9 -0
- package/dist/documents/internal.d.ts.map +1 -0
- package/dist/documents/internal.js +9 -0
- package/dist/documents/internal.js.map +1 -0
- package/dist/documents/keyed-slot.d.ts +103 -0
- package/dist/documents/keyed-slot.d.ts.map +1 -0
- package/dist/documents/keyed-slot.js +395 -0
- package/dist/documents/keyed-slot.js.map +1 -0
- package/dist/documents/line.d.ts +7 -0
- package/dist/documents/line.d.ts.map +1 -0
- package/dist/documents/line.js +14 -0
- package/dist/documents/line.js.map +1 -0
- package/dist/documents/persistence.d.ts +104 -0
- package/dist/documents/persistence.d.ts.map +1 -0
- package/dist/documents/persistence.js +129 -0
- package/dist/documents/persistence.js.map +1 -0
- package/dist/documents/residency.d.ts +31 -0
- package/dist/documents/residency.d.ts.map +1 -0
- package/dist/documents/residency.js +93 -0
- package/dist/documents/residency.js.map +1 -0
- package/dist/documents/slot.d.ts +109 -0
- package/dist/documents/slot.d.ts.map +1 -0
- package/dist/documents/slot.js +181 -0
- package/dist/documents/slot.js.map +1 -0
- package/dist/documents/transaction.d.ts +143 -0
- package/dist/documents/transaction.d.ts.map +1 -0
- package/dist/documents/transaction.js +442 -0
- package/dist/documents/transaction.js.map +1 -0
- package/dist/host/activity.d.ts +31 -0
- package/dist/host/activity.d.ts.map +1 -0
- package/dist/host/activity.js +40 -0
- package/dist/host/activity.js.map +1 -0
- package/dist/host/adapted.d.ts +49 -0
- package/dist/host/adapted.d.ts.map +1 -0
- package/dist/host/adapted.js +214 -0
- package/dist/host/adapted.js.map +1 -0
- package/dist/host/attempt.d.ts +308 -0
- package/dist/host/attempt.d.ts.map +1 -0
- package/dist/host/attempt.js +1199 -0
- package/dist/host/attempt.js.map +1 -0
- package/dist/host/backoff.d.ts +29 -0
- package/dist/host/backoff.d.ts.map +1 -0
- package/dist/host/backoff.js +69 -0
- package/dist/host/backoff.js.map +1 -0
- package/dist/host/ctx.d.ts +94 -0
- package/dist/host/ctx.d.ts.map +1 -0
- package/dist/host/ctx.js +200 -0
- package/dist/host/ctx.js.map +1 -0
- package/dist/host/deadline.d.ts +12 -0
- package/dist/host/deadline.d.ts.map +1 -0
- package/dist/host/deadline.js +40 -0
- package/dist/host/deadline.js.map +1 -0
- package/dist/host/dependencies.d.ts +65 -0
- package/dist/host/dependencies.d.ts.map +1 -0
- package/dist/host/dependencies.js +115 -0
- package/dist/host/dependencies.js.map +1 -0
- package/dist/host/destination.d.ts +48 -0
- package/dist/host/destination.d.ts.map +1 -0
- package/dist/host/destination.js +101 -0
- package/dist/host/destination.js.map +1 -0
- package/dist/host/facet.d.ts +84 -0
- package/dist/host/facet.d.ts.map +1 -0
- package/dist/host/facet.js +55 -0
- package/dist/host/facet.js.map +1 -0
- package/dist/host/follow.d.ts +52 -0
- package/dist/host/follow.d.ts.map +1 -0
- package/dist/host/follow.js +207 -0
- package/dist/host/follow.js.map +1 -0
- package/dist/host/host.d.ts +571 -0
- package/dist/host/host.d.ts.map +1 -0
- package/dist/host/host.js +1318 -0
- package/dist/host/host.js.map +1 -0
- package/dist/host/index.d.ts +17 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +6 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/internal.d.ts +11 -0
- package/dist/host/internal.d.ts.map +1 -0
- package/dist/host/internal.js +9 -0
- package/dist/host/internal.js.map +1 -0
- package/dist/host/members.d.ts +50 -0
- package/dist/host/members.d.ts.map +1 -0
- package/dist/host/members.js +107 -0
- package/dist/host/members.js.map +1 -0
- package/dist/host/native.d.ts +64 -0
- package/dist/host/native.d.ts.map +1 -0
- package/dist/host/native.js +126 -0
- package/dist/host/native.js.map +1 -0
- package/dist/host/object.d.ts +331 -0
- package/dist/host/object.d.ts.map +1 -0
- package/dist/host/object.js +1296 -0
- package/dist/host/object.js.map +1 -0
- package/dist/host/old-work.d.ts +34 -0
- package/dist/host/old-work.d.ts.map +1 -0
- package/dist/host/old-work.js +52 -0
- package/dist/host/old-work.js.map +1 -0
- package/dist/host/parked.d.ts +23 -0
- package/dist/host/parked.d.ts.map +1 -0
- package/dist/host/parked.js +79 -0
- package/dist/host/parked.js.map +1 -0
- package/dist/host/presence.d.ts +34 -0
- package/dist/host/presence.d.ts.map +1 -0
- package/dist/host/presence.js +117 -0
- package/dist/host/presence.js.map +1 -0
- package/dist/host/readiness.d.ts +27 -0
- package/dist/host/readiness.d.ts.map +1 -0
- package/dist/host/readiness.js +134 -0
- package/dist/host/readiness.js.map +1 -0
- package/dist/host/ref-state.d.ts +53 -0
- package/dist/host/ref-state.d.ts.map +1 -0
- package/dist/host/ref-state.js +83 -0
- package/dist/host/ref-state.js.map +1 -0
- package/dist/host/reference-keys.d.ts +36 -0
- package/dist/host/reference-keys.d.ts.map +1 -0
- package/dist/host/reference-keys.js +168 -0
- package/dist/host/reference-keys.js.map +1 -0
- package/dist/host/reference-source.d.ts +65 -0
- package/dist/host/reference-source.d.ts.map +1 -0
- package/dist/host/reference-source.js +285 -0
- package/dist/host/reference-source.js.map +1 -0
- package/dist/host/reference.d.ts +321 -0
- package/dist/host/reference.d.ts.map +1 -0
- package/dist/host/reference.js +797 -0
- package/dist/host/reference.js.map +1 -0
- package/dist/host/reload-cycle.d.ts +16 -0
- package/dist/host/reload-cycle.d.ts.map +1 -0
- package/dist/host/reload-cycle.js +81 -0
- package/dist/host/reload-cycle.js.map +1 -0
- package/dist/host/retry-on.d.ts +28 -0
- package/dist/host/retry-on.d.ts.map +1 -0
- package/dist/host/retry-on.js +52 -0
- package/dist/host/retry-on.js.map +1 -0
- package/dist/host/revocation.d.ts +16 -0
- package/dist/host/revocation.d.ts.map +1 -0
- package/dist/host/revocation.js +27 -0
- package/dist/host/revocation.js.map +1 -0
- package/dist/host/root.d.ts +37 -0
- package/dist/host/root.d.ts.map +1 -0
- package/dist/host/root.js +68 -0
- package/dist/host/root.js.map +1 -0
- package/dist/host/route.d.ts +64 -0
- package/dist/host/route.d.ts.map +1 -0
- package/dist/host/route.js +227 -0
- package/dist/host/route.js.map +1 -0
- package/dist/host/routines.d.ts +78 -0
- package/dist/host/routines.d.ts.map +1 -0
- package/dist/host/routines.js +398 -0
- package/dist/host/routines.js.map +1 -0
- package/dist/host/sleep.d.ts +9 -0
- package/dist/host/sleep.d.ts.map +1 -0
- package/dist/host/sleep.js +40 -0
- package/dist/host/sleep.js.map +1 -0
- package/dist/host/staging.d.ts +94 -0
- package/dist/host/staging.d.ts.map +1 -0
- package/dist/host/staging.js +304 -0
- package/dist/host/staging.js.map +1 -0
- package/dist/host/unbound-clock.d.ts +23 -0
- package/dist/host/unbound-clock.d.ts.map +1 -0
- package/dist/host/unbound-clock.js +58 -0
- package/dist/host/unbound-clock.js.map +1 -0
- package/dist/host/unbound.d.ts +37 -0
- package/dist/host/unbound.d.ts.map +1 -0
- package/dist/host/unbound.js +88 -0
- package/dist/host/unbound.js.map +1 -0
- package/dist/host/uuid.d.ts +3 -0
- package/dist/host/uuid.d.ts.map +1 -0
- package/dist/host/uuid.js +38 -0
- package/dist/host/uuid.js.map +1 -0
- package/dist/index.d.ts +29 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -9
- package/dist/index.js.map +1 -1
- package/dist/jobs/definition.d.ts +96 -0
- package/dist/jobs/definition.d.ts.map +1 -0
- package/dist/jobs/definition.js +83 -0
- package/dist/jobs/definition.js.map +1 -0
- package/dist/jobs/index.d.ts +5 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +3 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/internal.d.ts +3 -0
- package/dist/jobs/internal.d.ts.map +1 -0
- package/dist/jobs/internal.js +4 -0
- package/dist/jobs/internal.js.map +1 -0
- package/dist/jobs/job.d.ts +149 -0
- package/dist/jobs/job.d.ts.map +1 -0
- package/dist/jobs/job.js +387 -0
- package/dist/jobs/job.js.map +1 -0
- package/dist/jobs/persisted.d.ts +38 -0
- package/dist/jobs/persisted.d.ts.map +1 -0
- package/dist/jobs/persisted.js +95 -0
- package/dist/jobs/persisted.js.map +1 -0
- package/dist/jobs/records.d.ts +231 -0
- package/dist/jobs/records.d.ts.map +1 -0
- package/dist/jobs/records.js +871 -0
- package/dist/jobs/records.js.map +1 -0
- package/dist/jobs/run-states.d.ts +69 -0
- package/dist/jobs/run-states.d.ts.map +1 -0
- package/dist/jobs/run-states.js +228 -0
- package/dist/jobs/run-states.js.map +1 -0
- package/dist/jobs/run.d.ts +117 -0
- package/dist/jobs/run.d.ts.map +1 -0
- package/dist/jobs/run.js +204 -0
- package/dist/jobs/run.js.map +1 -0
- package/dist/jobs/running.d.ts +44 -0
- package/dist/jobs/running.d.ts.map +1 -0
- package/dist/jobs/running.js +117 -0
- package/dist/jobs/running.js.map +1 -0
- package/dist/jobs/stored.d.ts +63 -0
- package/dist/jobs/stored.d.ts.map +1 -0
- package/dist/jobs/stored.js +55 -0
- package/dist/jobs/stored.js.map +1 -0
- package/dist/link/binary.d.ts +4 -0
- package/dist/link/binary.d.ts.map +1 -0
- package/dist/link/binary.js +544 -0
- package/dist/link/binary.js.map +1 -0
- package/dist/link/channel.d.ts +68 -0
- package/dist/link/channel.d.ts.map +1 -0
- package/dist/link/channel.js +215 -0
- package/dist/link/channel.js.map +1 -0
- package/dist/link/errors.d.ts +7 -0
- package/dist/link/errors.d.ts.map +1 -0
- package/dist/link/errors.js +21 -0
- package/dist/link/errors.js.map +1 -0
- package/dist/link/index.d.ts +8 -0
- package/dist/link/index.d.ts.map +1 -0
- package/dist/link/index.js +8 -0
- package/dist/link/index.js.map +1 -0
- package/dist/link/internal.d.ts +9 -0
- package/dist/link/internal.d.ts.map +1 -0
- package/dist/link/internal.js +10 -0
- package/dist/link/internal.js.map +1 -0
- package/dist/link/ipc.d.ts +22 -0
- package/dist/link/ipc.d.ts.map +1 -0
- package/dist/link/ipc.js +64 -0
- package/dist/link/ipc.js.map +1 -0
- package/dist/link/link.d.ts +34 -0
- package/dist/link/link.d.ts.map +1 -0
- package/dist/link/link.js +87 -0
- package/dist/link/link.js.map +1 -0
- package/dist/link/message.d.ts +262 -0
- package/dist/link/message.d.ts.map +1 -0
- package/dist/link/message.js +156 -0
- package/dist/link/message.js.map +1 -0
- package/dist/link/part.d.ts +80 -0
- package/dist/link/part.d.ts.map +1 -0
- package/dist/link/part.js +165 -0
- package/dist/link/part.js.map +1 -0
- package/dist/link/text.d.ts +6 -0
- package/dist/link/text.d.ts.map +1 -0
- package/dist/link/text.js +355 -0
- package/dist/link/text.js.map +1 -0
- package/dist/link/values.d.ts +40 -0
- package/dist/link/values.d.ts.map +1 -0
- package/dist/link/values.js +121 -0
- package/dist/link/values.js.map +1 -0
- package/dist/link/websocket.d.ts +26 -0
- package/dist/link/websocket.d.ts.map +1 -0
- package/dist/link/websocket.js +91 -0
- package/dist/link/websocket.js.map +1 -0
- package/dist/node/app/app.d.ts +269 -0
- package/dist/node/app/app.d.ts.map +1 -0
- package/dist/node/app/app.js +513 -0
- package/dist/node/app/app.js.map +1 -0
- package/dist/node/app/archive.d.ts +37 -0
- package/dist/node/app/archive.d.ts.map +1 -0
- package/dist/node/app/archive.js +204 -0
- package/dist/node/app/archive.js.map +1 -0
- package/dist/node/app/blobs.d.ts +23 -0
- package/dist/node/app/blobs.d.ts.map +1 -0
- package/dist/node/app/blobs.js +64 -0
- package/dist/node/app/blobs.js.map +1 -0
- package/dist/node/app/data.d.ts +35 -0
- package/dist/node/app/data.d.ts.map +1 -0
- package/dist/node/app/data.js +44 -0
- package/dist/node/app/data.js.map +1 -0
- package/dist/node/app/ephemeral-sessions.d.ts +20 -0
- package/dist/node/app/ephemeral-sessions.d.ts.map +1 -0
- package/dist/node/app/ephemeral-sessions.js +69 -0
- package/dist/node/app/ephemeral-sessions.js.map +1 -0
- package/dist/node/app/ephemeral.d.ts +11 -0
- package/dist/node/app/ephemeral.d.ts.map +1 -0
- package/dist/node/app/ephemeral.js +34 -0
- package/dist/node/app/ephemeral.js.map +1 -0
- package/dist/node/app/files-copy.d.ts +13 -0
- package/dist/node/app/files-copy.d.ts.map +1 -0
- package/dist/node/app/files-copy.js +86 -0
- package/dist/node/app/files-copy.js.map +1 -0
- package/dist/node/app/files-entry.d.ts +4 -0
- package/dist/node/app/files-entry.d.ts.map +1 -0
- package/dist/node/app/files-entry.js +7 -0
- package/dist/node/app/files-entry.js.map +1 -0
- package/dist/node/app/files-index.d.ts +180 -0
- package/dist/node/app/files-index.d.ts.map +1 -0
- package/dist/node/app/files-index.js +535 -0
- package/dist/node/app/files-index.js.map +1 -0
- package/dist/node/app/files.d.ts +363 -0
- package/dist/node/app/files.d.ts.map +1 -0
- package/dist/node/app/files.js +368 -0
- package/dist/node/app/files.js.map +1 -0
- package/dist/node/app/folder-views.d.ts +21 -0
- package/dist/node/app/folder-views.d.ts.map +1 -0
- package/dist/node/app/folder-views.js +55 -0
- package/dist/node/app/folder-views.js.map +1 -0
- package/dist/node/app/index.d.ts +12 -0
- package/dist/node/app/index.d.ts.map +1 -0
- package/dist/node/app/index.js +15 -0
- package/dist/node/app/index.js.map +1 -0
- package/dist/node/app/info.d.ts +66 -0
- package/dist/node/app/info.d.ts.map +1 -0
- package/dist/node/app/info.js +37 -0
- package/dist/node/app/info.js.map +1 -0
- package/dist/node/app/invite.d.ts +5 -0
- package/dist/node/app/invite.d.ts.map +1 -0
- package/dist/node/app/invite.js +64 -0
- package/dist/node/app/invite.js.map +1 -0
- package/dist/node/app/layout.d.ts +36 -0
- package/dist/node/app/layout.d.ts.map +1 -0
- package/dist/node/app/layout.js +87 -0
- package/dist/node/app/layout.js.map +1 -0
- package/dist/node/app/owner.d.ts +31 -0
- package/dist/node/app/owner.d.ts.map +1 -0
- package/dist/node/app/owner.js +104 -0
- package/dist/node/app/owner.js.map +1 -0
- package/dist/node/app/pairing.d.ts +55 -0
- package/dist/node/app/pairing.d.ts.map +1 -0
- package/dist/node/app/pairing.js +183 -0
- package/dist/node/app/pairing.js.map +1 -0
- package/dist/node/app/secrets.d.ts +16 -0
- package/dist/node/app/secrets.d.ts.map +1 -0
- package/dist/node/app/secrets.js +72 -0
- package/dist/node/app/secrets.js.map +1 -0
- package/dist/node/app/sessions.d.ts +72 -0
- package/dist/node/app/sessions.d.ts.map +1 -0
- package/dist/node/app/sessions.js +222 -0
- package/dist/node/app/sessions.js.map +1 -0
- package/dist/node/app/tar.d.ts +24 -0
- package/dist/node/app/tar.d.ts.map +1 -0
- package/dist/node/app/tar.js +167 -0
- package/dist/node/app/tar.js.map +1 -0
- package/dist/node/app/uploads.d.ts +37 -0
- package/dist/node/app/uploads.d.ts.map +1 -0
- package/dist/node/app/uploads.js +157 -0
- package/dist/node/app/uploads.js.map +1 -0
- package/dist/node/app/users.d.ts +37 -0
- package/dist/node/app/users.d.ts.map +1 -0
- package/dist/node/app/users.js +62 -0
- package/dist/node/app/users.js.map +1 -0
- package/dist/node/app/worker.d.ts +18 -0
- package/dist/node/app/worker.d.ts.map +1 -0
- package/dist/node/app/worker.js +84 -0
- package/dist/node/app/worker.js.map +1 -0
- package/dist/node/compression.d.ts +7 -0
- package/dist/node/compression.d.ts.map +1 -0
- package/dist/node/compression.js +25 -0
- package/dist/node/compression.js.map +1 -0
- package/dist/node/http/admission.d.ts +63 -0
- package/dist/node/http/admission.d.ts.map +1 -0
- package/dist/node/http/admission.js +134 -0
- package/dist/node/http/admission.js.map +1 -0
- package/dist/node/http/authenticate.d.ts +21 -0
- package/dist/node/http/authenticate.d.ts.map +1 -0
- package/dist/node/http/authenticate.js +34 -0
- package/dist/node/http/authenticate.js.map +1 -0
- package/dist/node/http/cookies.d.ts +32 -0
- package/dist/node/http/cookies.d.ts.map +1 -0
- package/dist/node/http/cookies.js +70 -0
- package/dist/node/http/cookies.js.map +1 -0
- package/dist/node/http/file.d.ts +23 -0
- package/dist/node/http/file.d.ts.map +1 -0
- package/dist/node/http/file.js +94 -0
- package/dist/node/http/file.js.map +1 -0
- package/dist/node/http/headers.d.ts +37 -0
- package/dist/node/http/headers.d.ts.map +1 -0
- package/dist/node/http/headers.js +136 -0
- package/dist/node/http/headers.js.map +1 -0
- package/dist/node/http/http.d.ts +111 -0
- package/dist/node/http/http.d.ts.map +1 -0
- package/dist/node/http/http.js +524 -0
- package/dist/node/http/http.js.map +1 -0
- package/dist/node/http/incoming.d.ts +19 -0
- package/dist/node/http/incoming.d.ts.map +1 -0
- package/dist/node/http/incoming.js +31 -0
- package/dist/node/http/incoming.js.map +1 -0
- package/dist/node/http/index.d.ts +11 -0
- package/dist/node/http/index.d.ts.map +1 -0
- package/dist/node/http/index.js +12 -0
- package/dist/node/http/index.js.map +1 -0
- package/dist/node/http/node.d.ts +78 -0
- package/dist/node/http/node.d.ts.map +1 -0
- package/dist/node/http/node.js +291 -0
- package/dist/node/http/node.js.map +1 -0
- package/dist/node/http/request.d.ts +60 -0
- package/dist/node/http/request.d.ts.map +1 -0
- package/dist/node/http/request.js +118 -0
- package/dist/node/http/request.js.map +1 -0
- package/dist/node/http/response.d.ts +63 -0
- package/dist/node/http/response.d.ts.map +1 -0
- package/dist/node/http/response.js +202 -0
- package/dist/node/http/response.js.map +1 -0
- package/dist/node/http/router.d.ts +132 -0
- package/dist/node/http/router.d.ts.map +1 -0
- package/dist/node/http/router.js +267 -0
- package/dist/node/http/router.js.map +1 -0
- package/dist/node/http/upgrades.d.ts +61 -0
- package/dist/node/http/upgrades.d.ts.map +1 -0
- package/dist/node/http/upgrades.js +192 -0
- package/dist/node/http/upgrades.js.map +1 -0
- package/dist/node/plugins/base-inputs.d.ts +14 -0
- package/dist/node/plugins/base-inputs.d.ts.map +1 -0
- package/dist/node/plugins/base-inputs.js +33 -0
- package/dist/node/plugins/base-inputs.js.map +1 -0
- package/dist/node/plugins/build.d.ts +77 -0
- package/dist/node/plugins/build.d.ts.map +1 -0
- package/dist/node/plugins/build.js +576 -0
- package/dist/node/plugins/build.js.map +1 -0
- package/dist/node/plugins/css-modules.d.ts +13 -0
- package/dist/node/plugins/css-modules.d.ts.map +1 -0
- package/dist/node/plugins/css-modules.js +58 -0
- package/dist/node/plugins/css-modules.js.map +1 -0
- package/dist/node/plugins/discover.d.ts +67 -0
- package/dist/node/plugins/discover.d.ts.map +1 -0
- package/dist/node/plugins/discover.js +369 -0
- package/dist/node/plugins/discover.js.map +1 -0
- package/dist/node/plugins/evaluate.d.ts +33 -0
- package/dist/node/plugins/evaluate.d.ts.map +1 -0
- package/dist/node/plugins/evaluate.js +121 -0
- package/dist/node/plugins/evaluate.js.map +1 -0
- package/dist/node/plugins/index.d.ts +11 -0
- package/dist/node/plugins/index.d.ts.map +1 -0
- package/dist/node/plugins/index.js +13 -0
- package/dist/node/plugins/index.js.map +1 -0
- package/dist/node/plugins/install.d.ts +38 -0
- package/dist/node/plugins/install.d.ts.map +1 -0
- package/dist/node/plugins/install.js +213 -0
- package/dist/node/plugins/install.js.map +1 -0
- package/dist/node/plugins/plugins.d.ts +162 -0
- package/dist/node/plugins/plugins.d.ts.map +1 -0
- package/dist/node/plugins/plugins.js +244 -0
- package/dist/node/plugins/plugins.js.map +1 -0
- package/dist/node/plugins/runtime.d.ts +57 -0
- package/dist/node/plugins/runtime.d.ts.map +1 -0
- package/dist/node/plugins/runtime.js +92 -0
- package/dist/node/plugins/runtime.js.map +1 -0
- package/dist/node/plugins/stack.d.ts +16 -0
- package/dist/node/plugins/stack.d.ts.map +1 -0
- package/dist/node/plugins/stack.js +61 -0
- package/dist/node/plugins/stack.js.map +1 -0
- package/dist/node/plugins/testing.d.ts +58 -0
- package/dist/node/plugins/testing.d.ts.map +1 -0
- package/dist/node/plugins/testing.js +210 -0
- package/dist/node/plugins/testing.js.map +1 -0
- package/dist/node/plugins/watcher.d.ts +69 -0
- package/dist/node/plugins/watcher.d.ts.map +1 -0
- package/dist/node/plugins/watcher.js +622 -0
- package/dist/node/plugins/watcher.js.map +1 -0
- package/dist/node/surfaces/bundle.d.ts +31 -0
- package/dist/node/surfaces/bundle.d.ts.map +1 -0
- package/dist/node/surfaces/bundle.js +118 -0
- package/dist/node/surfaces/bundle.js.map +1 -0
- package/dist/node/surfaces/current.d.ts +17 -0
- package/dist/node/surfaces/current.d.ts.map +1 -0
- package/dist/node/surfaces/current.js +54 -0
- package/dist/node/surfaces/current.js.map +1 -0
- package/dist/node/surfaces/index.d.ts +6 -0
- package/dist/node/surfaces/index.d.ts.map +1 -0
- package/dist/node/surfaces/index.js +6 -0
- package/dist/node/surfaces/index.js.map +1 -0
- package/dist/node/surfaces/published.d.ts +27 -0
- package/dist/node/surfaces/published.d.ts.map +1 -0
- package/dist/node/surfaces/published.js +142 -0
- package/dist/node/surfaces/published.js.map +1 -0
- package/dist/node/surfaces/served.d.ts +15 -0
- package/dist/node/surfaces/served.d.ts.map +1 -0
- package/dist/node/surfaces/served.js +42 -0
- package/dist/node/surfaces/served.js.map +1 -0
- package/dist/node/surfaces/surface-build.d.ts +53 -0
- package/dist/node/surfaces/surface-build.d.ts.map +1 -0
- package/dist/node/surfaces/surface-build.js +105 -0
- package/dist/node/surfaces/surface-build.js.map +1 -0
- package/dist/node/surfaces/tui.d.ts +40 -0
- package/dist/node/surfaces/tui.d.ts.map +1 -0
- package/dist/node/surfaces/tui.js +55 -0
- package/dist/node/surfaces/tui.js.map +1 -0
- package/dist/node/surfaces/web.d.ts +56 -0
- package/dist/node/surfaces/web.d.ts.map +1 -0
- package/dist/node/surfaces/web.js +108 -0
- package/dist/node/surfaces/web.js.map +1 -0
- package/dist/node/tui/actions.d.ts +49 -0
- package/dist/node/tui/actions.d.ts.map +1 -0
- package/dist/node/tui/actions.js +195 -0
- package/dist/node/tui/actions.js.map +1 -0
- package/dist/node/tui/credentials.d.ts +17 -0
- package/dist/node/tui/credentials.d.ts.map +1 -0
- package/dist/node/tui/credentials.js +54 -0
- package/dist/node/tui/credentials.js.map +1 -0
- package/dist/node/tui/filter.d.ts +5 -0
- package/dist/node/tui/filter.d.ts.map +1 -0
- package/dist/node/tui/filter.js +79 -0
- package/dist/node/tui/filter.js.map +1 -0
- package/dist/node/tui/index.d.ts +6 -0
- package/dist/node/tui/index.d.ts.map +1 -0
- package/dist/node/tui/index.js +6 -0
- package/dist/node/tui/index.js.map +1 -0
- package/dist/node/tui/launcher.d.ts +40 -0
- package/dist/node/tui/launcher.d.ts.map +1 -0
- package/dist/node/tui/launcher.js +439 -0
- package/dist/node/tui/launcher.js.map +1 -0
- package/dist/node/tui/pipe.d.ts +18 -0
- package/dist/node/tui/pipe.d.ts.map +1 -0
- package/dist/node/tui/pipe.js +134 -0
- package/dist/node/tui/pipe.js.map +1 -0
- package/dist/node/tui/sandbox.d.ts +54 -0
- package/dist/node/tui/sandbox.d.ts.map +1 -0
- package/dist/node/tui/sandbox.js +431 -0
- package/dist/node/tui/sandbox.js.map +1 -0
- package/dist/node/workers/base.d.ts +30 -0
- package/dist/node/workers/base.d.ts.map +1 -0
- package/dist/node/workers/base.js +255 -0
- package/dist/node/workers/base.js.map +1 -0
- package/dist/node/workers/child.d.ts +4 -0
- package/dist/node/workers/child.d.ts.map +1 -0
- package/dist/node/workers/child.js +6 -0
- package/dist/node/workers/child.js.map +1 -0
- package/dist/node/workers/control.d.ts +83 -0
- package/dist/node/workers/control.d.ts.map +1 -0
- package/dist/node/workers/control.js +77 -0
- package/dist/node/workers/control.js.map +1 -0
- package/dist/node/workers/index.d.ts +4 -0
- package/dist/node/workers/index.d.ts.map +1 -0
- package/dist/node/workers/index.js +7 -0
- package/dist/node/workers/index.js.map +1 -0
- package/dist/node/workers/lock.d.ts +30 -0
- package/dist/node/workers/lock.d.ts.map +1 -0
- package/dist/node/workers/lock.js +180 -0
- package/dist/node/workers/lock.js.map +1 -0
- package/dist/node/workers/main.d.ts +46 -0
- package/dist/node/workers/main.d.ts.map +1 -0
- package/dist/node/workers/main.js +230 -0
- package/dist/node/workers/main.js.map +1 -0
- package/dist/node/workers/process.d.ts +42 -0
- package/dist/node/workers/process.d.ts.map +1 -0
- package/dist/node/workers/process.js +125 -0
- package/dist/node/workers/process.js.map +1 -0
- package/dist/node/workers/workers.d.ts +122 -0
- package/dist/node/workers/workers.d.ts.map +1 -0
- package/dist/node/workers/workers.js +677 -0
- package/dist/node/workers/workers.js.map +1 -0
- package/dist/output.d.ts +1 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +4 -2
- package/dist/output.js.map +1 -1
- package/dist/react/hooks.d.ts +43 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/hooks.js +82 -0
- package/dist/react/hooks.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +4 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/stores.d.ts +9 -0
- package/dist/react/stores.d.ts.map +1 -0
- package/dist/react/stores.js +37 -0
- package/dist/react/stores.js.map +1 -0
- package/dist/registries/contribution.d.ts +50 -0
- package/dist/registries/contribution.d.ts.map +1 -0
- package/dist/registries/contribution.js +129 -0
- package/dist/registries/contribution.js.map +1 -0
- package/dist/registries/entries.d.ts +18 -0
- package/dist/registries/entries.d.ts.map +1 -0
- package/dist/registries/entries.js +42 -0
- package/dist/registries/entries.js.map +1 -0
- package/dist/registries/index.d.ts +3 -0
- package/dist/registries/index.d.ts.map +1 -0
- package/dist/registries/index.js +5 -0
- package/dist/registries/index.js.map +1 -0
- package/dist/registries/internal.d.ts +4 -0
- package/dist/registries/internal.d.ts.map +1 -0
- package/dist/registries/internal.js +5 -0
- package/dist/registries/internal.js.map +1 -0
- package/dist/registries/record.d.ts +115 -0
- package/dist/registries/record.d.ts.map +1 -0
- package/dist/registries/record.js +283 -0
- package/dist/registries/record.js.map +1 -0
- package/dist/registries/registry.d.ts +74 -0
- package/dist/registries/registry.d.ts.map +1 -0
- package/dist/registries/registry.js +14 -0
- package/dist/registries/registry.js.map +1 -0
- package/dist/registries/value.d.ts +48 -0
- package/dist/registries/value.d.ts.map +1 -0
- package/dist/registries/value.js +224 -0
- package/dist/registries/value.js.map +1 -0
- package/dist/remote/calls.d.ts +25 -0
- package/dist/remote/calls.d.ts.map +1 -0
- package/dist/remote/calls.js +62 -0
- package/dist/remote/calls.js.map +1 -0
- package/dist/remote/consumer.d.ts +43 -0
- package/dist/remote/consumer.d.ts.map +1 -0
- package/dist/remote/consumer.js +350 -0
- package/dist/remote/consumer.js.map +1 -0
- package/dist/remote/hold.d.ts +141 -0
- package/dist/remote/hold.d.ts.map +1 -0
- package/dist/remote/hold.js +579 -0
- package/dist/remote/hold.js.map +1 -0
- package/dist/remote/host-link.d.ts +77 -0
- package/dist/remote/host-link.d.ts.map +1 -0
- package/dist/remote/host-link.js +184 -0
- package/dist/remote/host-link.js.map +1 -0
- package/dist/remote/internal.d.ts +6 -0
- package/dist/remote/internal.d.ts.map +1 -0
- package/dist/remote/internal.js +6 -0
- package/dist/remote/internal.js.map +1 -0
- package/dist/remote/path.d.ts +46 -0
- package/dist/remote/path.d.ts.map +1 -0
- package/dist/remote/path.js +73 -0
- package/dist/remote/path.js.map +1 -0
- package/dist/remote/provider.d.ts +89 -0
- package/dist/remote/provider.d.ts.map +1 -0
- package/dist/remote/provider.js +597 -0
- package/dist/remote/provider.js.map +1 -0
- package/dist/remote/relay.d.ts +69 -0
- package/dist/remote/relay.d.ts.map +1 -0
- package/dist/remote/relay.js +219 -0
- package/dist/remote/relay.js.map +1 -0
- package/dist/remote/remote-object.d.ts +138 -0
- package/dist/remote/remote-object.d.ts.map +1 -0
- package/dist/remote/remote-object.js +492 -0
- package/dist/remote/remote-object.js.map +1 -0
- package/dist/remote/replica.d.ts +59 -0
- package/dist/remote/replica.d.ts.map +1 -0
- package/dist/remote/replica.js +125 -0
- package/dist/remote/replica.js.map +1 -0
- package/dist/sqlite/cloudflare.d.ts +2 -0
- package/dist/sqlite/cloudflare.d.ts.map +1 -1
- package/dist/sqlite/cloudflare.js +10 -0
- package/dist/sqlite/cloudflare.js.map +1 -1
- package/dist/sqlite/database.d.ts +5 -2
- package/dist/sqlite/database.d.ts.map +1 -1
- package/dist/sqlite/database.js.map +1 -1
- package/dist/sqlite/node.d.ts +13 -2
- package/dist/sqlite/node.d.ts.map +1 -1
- package/dist/sqlite/node.js +31 -8
- package/dist/sqlite/node.js.map +1 -1
- package/dist/state/batch.d.ts +64 -0
- package/dist/state/batch.d.ts.map +1 -0
- package/dist/state/batch.js +164 -0
- package/dist/state/batch.js.map +1 -0
- package/dist/state/derive.d.ts +52 -0
- package/dist/state/derive.d.ts.map +1 -0
- package/dist/state/derive.js +182 -0
- package/dist/state/derive.js.map +1 -0
- package/dist/state/index.d.ts +6 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +4 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/internal.d.ts +6 -0
- package/dist/state/internal.d.ts.map +1 -0
- package/dist/state/internal.js +8 -0
- package/dist/state/internal.js.map +1 -0
- package/dist/state/native-source.d.ts +106 -0
- package/dist/state/native-source.d.ts.map +1 -0
- package/dist/state/native-source.js +240 -0
- package/dist/state/native-source.js.map +1 -0
- package/dist/state/watchable.d.ts +114 -0
- package/dist/state/watchable.d.ts.map +1 -0
- package/dist/state/watchable.js +156 -0
- package/dist/state/watchable.js.map +1 -0
- package/dist/state/writable.d.ts +32 -0
- package/dist/state/writable.d.ts.map +1 -0
- package/dist/state/writable.js +49 -0
- package/dist/state/writable.js.map +1 -0
- package/dist/store/adapter.d.ts +67 -0
- package/dist/store/adapter.d.ts.map +1 -0
- package/dist/store/adapter.js +118 -0
- package/dist/store/adapter.js.map +1 -0
- package/dist/store/allocator.d.ts +17 -0
- package/dist/store/allocator.d.ts.map +1 -0
- package/dist/store/allocator.js +30 -0
- package/dist/store/allocator.js.map +1 -0
- package/dist/store/applier.d.ts +8 -0
- package/dist/store/applier.d.ts.map +1 -0
- package/dist/store/applier.js +375 -0
- package/dist/store/applier.js.map +1 -0
- package/dist/store/apply-batch.d.ts +12 -0
- package/dist/store/apply-batch.d.ts.map +1 -0
- package/dist/store/apply-batch.js +83 -0
- package/dist/store/apply-batch.js.map +1 -0
- package/dist/store/archive.d.ts +32 -0
- package/dist/store/archive.d.ts.map +1 -0
- package/dist/store/archive.js +130 -0
- package/dist/store/archive.js.map +1 -0
- package/dist/store/backend.d.ts +10 -0
- package/dist/store/backend.d.ts.map +1 -0
- package/dist/store/backend.js +15 -0
- package/dist/store/backend.js.map +1 -0
- package/dist/store/catalog.d.ts +24 -0
- package/dist/store/catalog.d.ts.map +1 -0
- package/dist/store/catalog.js +17 -0
- package/dist/store/catalog.js.map +1 -0
- package/dist/store/claims.d.ts +23 -0
- package/dist/store/claims.d.ts.map +1 -0
- package/dist/store/claims.js +65 -0
- package/dist/store/claims.js.map +1 -0
- package/dist/store/columns.d.ts +77 -0
- package/dist/store/columns.d.ts.map +1 -0
- package/dist/store/columns.js +77 -0
- package/dist/store/columns.js.map +1 -0
- package/dist/store/engine.d.ts +176 -0
- package/dist/store/engine.d.ts.map +1 -0
- package/dist/store/engine.js +283 -0
- package/dist/store/engine.js.map +1 -0
- package/dist/store/evaluate.d.ts +17 -0
- package/dist/store/evaluate.d.ts.map +1 -0
- package/dist/store/evaluate.js +128 -0
- package/dist/store/evaluate.js.map +1 -0
- package/dist/store/export.d.ts +17 -0
- package/dist/store/export.d.ts.map +1 -0
- package/dist/store/export.js +200 -0
- package/dist/store/export.js.map +1 -0
- package/dist/store/expression.d.ts +150 -0
- package/dist/store/expression.d.ts.map +1 -0
- package/dist/store/expression.js +268 -0
- package/dist/store/expression.js.map +1 -0
- package/dist/store/import.d.ts +10 -0
- package/dist/store/import.d.ts.map +1 -0
- package/dist/store/import.js +276 -0
- package/dist/store/import.js.map +1 -0
- package/dist/store/index.d.ts +16 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +13 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/json-column.d.ts +33 -0
- package/dist/store/json-column.d.ts.map +1 -0
- package/dist/store/json-column.js +62 -0
- package/dist/store/json-column.js.map +1 -0
- package/dist/store/jsonl.d.ts +9 -0
- package/dist/store/jsonl.d.ts.map +1 -0
- package/dist/store/jsonl.js +61 -0
- package/dist/store/jsonl.js.map +1 -0
- package/dist/store/live-query.d.ts +108 -0
- package/dist/store/live-query.d.ts.map +1 -0
- package/dist/store/live-query.js +254 -0
- package/dist/store/live-query.js.map +1 -0
- package/dist/store/outbox.d.ts +26 -0
- package/dist/store/outbox.d.ts.map +1 -0
- package/dist/store/outbox.js +80 -0
- package/dist/store/outbox.js.map +1 -0
- package/dist/store/query.d.ts +39 -0
- package/dist/store/query.d.ts.map +1 -0
- package/dist/store/query.js +97 -0
- package/dist/store/query.js.map +1 -0
- package/dist/store/refusal.d.ts +15 -0
- package/dist/store/refusal.d.ts.map +1 -0
- package/dist/store/refusal.js +36 -0
- package/dist/store/refusal.js.map +1 -0
- package/dist/store/rows.d.ts +80 -0
- package/dist/store/rows.d.ts.map +1 -0
- package/dist/store/rows.js +183 -0
- package/dist/store/rows.js.map +1 -0
- package/dist/store/schema.d.ts +25 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/dist/store/schema.js +115 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/store/sql.d.ts +73 -0
- package/dist/store/sql.d.ts.map +1 -0
- package/dist/store/sql.js +234 -0
- package/dist/store/sql.js.map +1 -0
- package/dist/store/step.d.ts +50 -0
- package/dist/store/step.d.ts.map +1 -0
- package/dist/store/step.js +52 -0
- package/dist/store/step.js.map +1 -0
- package/dist/store/store.d.ts +171 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.js +818 -0
- package/dist/store/store.js.map +1 -0
- package/dist/store/table-changes.d.ts +29 -0
- package/dist/store/table-changes.d.ts.map +1 -0
- package/dist/store/table-changes.js +102 -0
- package/dist/store/table-changes.js.map +1 -0
- package/dist/store/table-evolve.d.ts +74 -0
- package/dist/store/table-evolve.d.ts.map +1 -0
- package/dist/store/table-evolve.js +201 -0
- package/dist/store/table-evolve.js.map +1 -0
- package/dist/store/table-handle.d.ts +73 -0
- package/dist/store/table-handle.d.ts.map +1 -0
- package/dist/store/table-handle.js +101 -0
- package/dist/store/table-handle.js.map +1 -0
- package/dist/store/table-history.d.ts +75 -0
- package/dist/store/table-history.d.ts.map +1 -0
- package/dist/store/table-history.js +42 -0
- package/dist/store/table-history.js.map +1 -0
- package/dist/store/table-migration.d.ts +16 -0
- package/dist/store/table-migration.d.ts.map +1 -0
- package/dist/store/table-migration.js +202 -0
- package/dist/store/table-migration.js.map +1 -0
- package/dist/store/table-writes.d.ts +125 -0
- package/dist/store/table-writes.d.ts.map +1 -0
- package/dist/store/table-writes.js +170 -0
- package/dist/store/table-writes.js.map +1 -0
- package/dist/store/table.d.ts +80 -0
- package/dist/store/table.d.ts.map +1 -0
- package/dist/store/table.js +103 -0
- package/dist/store/table.js.map +1 -0
- package/dist/store/text.d.ts +14 -0
- package/dist/store/text.d.ts.map +1 -0
- package/dist/store/text.js +51 -0
- package/dist/store/text.js.map +1 -0
- package/dist/store/writes.d.ts +5 -0
- package/dist/store/writes.d.ts.map +1 -0
- package/dist/store/writes.js +4 -0
- package/dist/store/writes.js.map +1 -0
- package/dist/surfaces/active-language.d.ts +20 -0
- package/dist/surfaces/active-language.d.ts.map +1 -0
- package/dist/surfaces/active-language.js +78 -0
- package/dist/surfaces/active-language.js.map +1 -0
- package/dist/surfaces/active-theme.d.ts +16 -0
- package/dist/surfaces/active-theme.d.ts.map +1 -0
- package/dist/surfaces/active-theme.js +47 -0
- package/dist/surfaces/active-theme.js.map +1 -0
- package/dist/surfaces/client.d.ts +96 -0
- package/dist/surfaces/client.d.ts.map +1 -0
- package/dist/surfaces/client.js +264 -0
- package/dist/surfaces/client.js.map +1 -0
- package/dist/surfaces/connection.d.ts +49 -0
- package/dist/surfaces/connection.d.ts.map +1 -0
- package/dist/surfaces/connection.js +142 -0
- package/dist/surfaces/connection.js.map +1 -0
- package/dist/surfaces/format.d.ts +5 -0
- package/dist/surfaces/format.d.ts.map +1 -0
- package/dist/surfaces/format.js +37 -0
- package/dist/surfaces/format.js.map +1 -0
- package/dist/surfaces/index.d.ts +15 -0
- package/dist/surfaces/index.d.ts.map +1 -0
- package/dist/surfaces/index.js +18 -0
- package/dist/surfaces/index.js.map +1 -0
- package/dist/surfaces/language.d.ts +53 -0
- package/dist/surfaces/language.d.ts.map +1 -0
- package/dist/surfaces/language.js +74 -0
- package/dist/surfaces/language.js.map +1 -0
- package/dist/surfaces/loaded.d.ts +42 -0
- package/dist/surfaces/loaded.d.ts.map +1 -0
- package/dist/surfaces/loaded.js +116 -0
- package/dist/surfaces/loaded.js.map +1 -0
- package/dist/surfaces/locale-choice.d.ts +25 -0
- package/dist/surfaces/locale-choice.d.ts.map +1 -0
- package/dist/surfaces/locale-choice.js +14 -0
- package/dist/surfaces/locale-choice.js.map +1 -0
- package/dist/surfaces/messages.d.ts +67 -0
- package/dist/surfaces/messages.d.ts.map +1 -0
- package/dist/surfaces/messages.js +112 -0
- package/dist/surfaces/messages.js.map +1 -0
- package/dist/surfaces/page-state.d.ts +14 -0
- package/dist/surfaces/page-state.d.ts.map +1 -0
- package/dist/surfaces/page-state.js +43 -0
- package/dist/surfaces/page-state.js.map +1 -0
- package/dist/surfaces/preference.d.ts +32 -0
- package/dist/surfaces/preference.d.ts.map +1 -0
- package/dist/surfaces/preference.js +72 -0
- package/dist/surfaces/preference.js.map +1 -0
- package/dist/surfaces/registered.d.ts +33 -0
- package/dist/surfaces/registered.d.ts.map +1 -0
- package/dist/surfaces/registered.js +51 -0
- package/dist/surfaces/registered.js.map +1 -0
- package/dist/surfaces/scripts.d.ts +84 -0
- package/dist/surfaces/scripts.d.ts.map +1 -0
- package/dist/surfaces/scripts.js +28 -0
- package/dist/surfaces/scripts.js.map +1 -0
- package/dist/surfaces/theme-choice.d.ts +31 -0
- package/dist/surfaces/theme-choice.d.ts.map +1 -0
- package/dist/surfaces/theme-choice.js +18 -0
- package/dist/surfaces/theme-choice.js.map +1 -0
- package/dist/surfaces/themes.d.ts +43 -0
- package/dist/surfaces/themes.d.ts.map +1 -0
- package/dist/surfaces/themes.js +110 -0
- package/dist/surfaces/themes.js.map +1 -0
- package/dist/surfaces/translations.d.ts +29 -0
- package/dist/surfaces/translations.d.ts.map +1 -0
- package/dist/surfaces/translations.js +57 -0
- package/dist/surfaces/translations.js.map +1 -0
- package/dist/sync/batch.d.ts +18 -0
- package/dist/sync/batch.d.ts.map +1 -0
- package/dist/sync/batch.js +125 -0
- package/dist/sync/batch.js.map +1 -0
- package/dist/sync/client.d.ts +166 -0
- package/dist/sync/client.d.ts.map +1 -0
- package/dist/sync/client.js +438 -0
- package/dist/sync/client.js.map +1 -0
- package/dist/sync/files.d.ts +46 -0
- package/dist/sync/files.d.ts.map +1 -0
- package/dist/sync/files.js +13 -0
- package/dist/sync/files.js.map +1 -0
- package/dist/sync/filesystem.d.ts +37 -0
- package/dist/sync/filesystem.d.ts.map +1 -0
- package/dist/sync/filesystem.js +185 -0
- package/dist/sync/filesystem.js.map +1 -0
- package/dist/sync/index.d.ts +8 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +9 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/lines.d.ts +18 -0
- package/dist/sync/lines.d.ts.map +1 -0
- package/dist/sync/lines.js +46 -0
- package/dist/sync/lines.js.map +1 -0
- package/dist/sync/remote.d.ts +130 -0
- package/dist/sync/remote.d.ts.map +1 -0
- package/dist/sync/remote.js +46 -0
- package/dist/sync/remote.js.map +1 -0
- package/dist/sync/state.d.ts +17 -0
- package/dist/sync/state.d.ts.map +1 -0
- package/dist/sync/state.js +40 -0
- package/dist/sync/state.js.map +1 -0
- package/dist/telemetry-ingest/batch.d.ts +70 -0
- package/dist/telemetry-ingest/batch.d.ts.map +1 -0
- package/dist/telemetry-ingest/batch.js +110 -0
- package/dist/telemetry-ingest/batch.js.map +1 -0
- package/dist/telemetry-ingest/facet.d.ts +21 -0
- package/dist/telemetry-ingest/facet.d.ts.map +1 -0
- package/dist/telemetry-ingest/facet.js +96 -0
- package/dist/telemetry-ingest/facet.js.map +1 -0
- package/dist/telemetry-ingest/index.d.ts +5 -0
- package/dist/telemetry-ingest/index.d.ts.map +1 -0
- package/dist/telemetry-ingest/index.js +8 -0
- package/dist/telemetry-ingest/index.js.map +1 -0
- package/dist/telemetry-ingest/recorder.d.ts +50 -0
- package/dist/telemetry-ingest/recorder.d.ts.map +1 -0
- package/dist/telemetry-ingest/recorder.js +298 -0
- package/dist/telemetry-ingest/recorder.js.map +1 -0
- package/dist/telemetry-ingest/sender.d.ts +14 -0
- package/dist/telemetry-ingest/sender.d.ts.map +1 -0
- package/dist/telemetry-ingest/sender.js +64 -0
- package/dist/telemetry-ingest/sender.js.map +1 -0
- package/dist/telemetry-sqlite/index.d.ts +13 -4
- package/dist/telemetry-sqlite/index.d.ts.map +1 -1
- package/dist/telemetry-sqlite/index.js +81 -241
- package/dist/telemetry-sqlite/index.js.map +1 -1
- package/dist/telemetry-sqlite/node.d.ts +13 -0
- package/dist/telemetry-sqlite/node.d.ts.map +1 -0
- package/dist/telemetry-sqlite/node.js +27 -0
- package/dist/telemetry-sqlite/node.js.map +1 -0
- package/dist/telemetry-sqlite/schema.d.ts +9 -0
- package/dist/telemetry-sqlite/schema.d.ts.map +1 -0
- package/dist/telemetry-sqlite/schema.js +61 -0
- package/dist/telemetry-sqlite/schema.js.map +1 -0
- package/dist/telemetry-sqlite/store.d.ts +3 -0
- package/dist/telemetry-sqlite/store.d.ts.map +1 -1
- package/dist/telemetry-sqlite/store.js +24 -13
- package/dist/telemetry-sqlite/store.js.map +1 -1
- package/dist/telemetry.d.ts +937 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +470 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tui/bridge.d.ts +112 -0
- package/dist/tui/bridge.d.ts.map +1 -0
- package/dist/tui/bridge.js +9 -0
- package/dist/tui/bridge.js.map +1 -0
- package/dist/tui/channel.d.ts +44 -0
- package/dist/tui/channel.d.ts.map +1 -0
- package/dist/tui/channel.js +150 -0
- package/dist/tui/channel.js.map +1 -0
- package/dist/tui/frames.d.ts +5 -0
- package/dist/tui/frames.d.ts.map +1 -0
- package/dist/tui/frames.js +52 -0
- package/dist/tui/frames.js.map +1 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +8 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/runtime.d.ts +46 -0
- package/dist/tui/runtime.d.ts.map +1 -0
- package/dist/tui/runtime.js +101 -0
- package/dist/tui/runtime.js.map +1 -0
- package/dist/tui/scope.d.ts +46 -0
- package/dist/tui/scope.d.ts.map +1 -0
- package/dist/tui/scope.js +141 -0
- package/dist/tui/scope.js.map +1 -0
- package/dist/tui/terminal.d.ts +15 -0
- package/dist/tui/terminal.d.ts.map +1 -0
- package/dist/tui/terminal.js +37 -0
- package/dist/tui/terminal.js.map +1 -0
- package/dist/tui/theme.d.ts +17 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +38 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/watch.d.ts +194 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +383 -0
- package/dist/watch.js.map +1 -0
- package/dist/web/environment.d.ts +4 -0
- package/dist/web/environment.d.ts.map +1 -0
- package/dist/web/environment.js +37 -0
- package/dist/web/environment.js.map +1 -0
- package/dist/web/index.d.ts +5 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +7 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/language.d.ts +7 -0
- package/dist/web/language.d.ts.map +1 -0
- package/dist/web/language.js +21 -0
- package/dist/web/language.js.map +1 -0
- package/dist/web/page.d.ts +29 -0
- package/dist/web/page.d.ts.map +1 -0
- package/dist/web/page.js +92 -0
- package/dist/web/page.js.map +1 -0
- package/dist/web/scripts.d.ts +23 -0
- package/dist/web/scripts.d.ts.map +1 -0
- package/dist/web/scripts.js +50 -0
- package/dist/web/scripts.js.map +1 -0
- package/dist/web/styles.d.ts +17 -0
- package/dist/web/styles.d.ts.map +1 -0
- package/dist/web/styles.js +218 -0
- package/dist/web/styles.js.map +1 -0
- package/dist/web/themes.d.ts +6 -0
- package/dist/web/themes.d.ts.map +1 -0
- package/dist/web/themes.js +31 -0
- package/dist/web/themes.js.map +1 -0
- package/docs/benchmarks.md +1036 -0
- package/docs/decisions.md +3436 -0
- package/docs/dependencies/book.md +1671 -0
- package/docs/dependencies/index.html +2641 -0
- package/docs/dependencies/model.md +330 -0
- package/docs/design.md +3065 -0
- package/docs/durable-observers/book.md +432 -0
- package/docs/durable-observers/index.html +517 -0
- package/docs/flow-control/book.md +333 -0
- package/docs/flow-control/fold/index.html +265 -0
- package/docs/flow-control/index.html +548 -0
- package/docs/flow-control/window/index.html +228 -0
- package/docs/guide-plugins-hosts/book.md +957 -0
- package/docs/guide-plugins-hosts/index.html +952 -0
- package/docs/http-workers/book.md +378 -0
- package/docs/http-workers/index.html +515 -0
- package/docs/i18n/book.md +217 -0
- package/docs/i18n/index.html +344 -0
- package/docs/layer-1.md +311 -0
- package/docs/layer-2.md +216 -0
- package/docs/p3-features/README.md +6 -0
- package/docs/p3-features/book.md +478 -0
- package/docs/plugin-authoring.md +276 -0
- package/docs/plugin-model/book.md +186 -0
- package/docs/plugin-model/index.html +310 -0
- package/docs/plugin-primer/book.md +273 -0
- package/docs/plugin-primer/index.html +430 -0
- package/docs/slice-1.md +236 -0
- package/docs/slice-10.md +288 -0
- package/docs/slice-11.md +114 -0
- package/docs/slice-12.md +132 -0
- package/docs/slice-13.md +121 -0
- package/docs/slice-2.md +174 -0
- package/docs/slice-3a.md +296 -0
- package/docs/slice-3b.md +197 -0
- package/docs/slice-4.md +146 -0
- package/docs/slice-4a.md +418 -0
- package/docs/slice-4b.md +208 -0
- package/docs/slice-5.md +281 -0
- package/docs/slice-6a.md +676 -0
- package/docs/slice-6b.md +332 -0
- package/docs/slice-7a.md +130 -0
- package/docs/slice-7b/book.md +608 -0
- package/docs/slice-7b/index.html +842 -0
- package/docs/slice-7b.md +255 -0
- package/docs/slice-7c.md +165 -0
- package/docs/slice-8.md +194 -0
- package/docs/slice-9.md +110 -0
- package/docs/slices.md +241 -0
- package/docs/store/book.md +670 -0
- package/docs/store/index.html +861 -0
- package/docs/store/walkthrough.md +193 -0
- package/docs/theming/book.md +223 -0
- package/docs/theming/index.html +371 -0
- package/docs/tutorial/book.md +2169 -0
- package/docs/tutorial/index.html +2112 -0
- package/docs/tutorial/screens/click-after.png +0 -0
- package/docs/tutorial/screens/click-before.png +0 -0
- package/docs/tutorial/screens/edited.png +0 -0
- package/docs/tutorial/screens/french.png +0 -0
- package/docs/tutorial/screens/harbor.png +0 -0
- package/docs/tutorial/screens/page.png +0 -0
- package/docs/tutorial/screens/traces-ada.png +0 -0
- package/docs/tutorial/screens/traces.png +0 -0
- package/package.json +114 -20
- package/src/delta/README.md +69 -0
- package/dist/cell.d.ts +0 -122
- package/dist/cell.d.ts.map +0 -1
- package/dist/cell.js +0 -356
- package/dist/cell.js.map +0 -1
- package/dist/cluster.d.ts +0 -27
- package/dist/cluster.d.ts.map +0 -1
- package/dist/cluster.js +0 -230
- package/dist/cluster.js.map +0 -1
- package/dist/connection.d.ts +0 -270
- package/dist/connection.d.ts.map +0 -1
- package/dist/connection.js +0 -1216
- package/dist/connection.js.map +0 -1
- package/dist/contract.d.ts +0 -208
- package/dist/contract.d.ts.map +0 -1
- package/dist/contract.js +0 -246
- package/dist/contract.js.map +0 -1
- package/dist/declare.d.ts +0 -33
- package/dist/declare.d.ts.map +0 -1
- package/dist/declare.js +0 -2
- package/dist/declare.js.map +0 -1
- package/dist/errors.d.ts +0 -28
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -59
- package/dist/errors.js.map +0 -1
- package/dist/host.d.ts +0 -348
- package/dist/host.d.ts.map +0 -1
- package/dist/host.js +0 -1000
- package/dist/host.js.map +0 -1
- package/dist/link.d.ts +0 -107
- package/dist/link.d.ts.map +0 -1
- package/dist/link.js +0 -355
- package/dist/link.js.map +0 -1
- package/dist/loader.d.ts +0 -4
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -73
- package/dist/loader.js.map +0 -1
- package/dist/manager.d.ts +0 -115
- package/dist/manager.d.ts.map +0 -1
- package/dist/manager.js +0 -345
- package/dist/manager.js.map +0 -1
- package/dist/node.d.ts +0 -4
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -4
- package/dist/node.js.map +0 -1
- package/dist/object.d.ts +0 -438
- package/dist/object.d.ts.map +0 -1
- package/dist/object.js +0 -1571
- package/dist/object.js.map +0 -1
- package/dist/publish.d.ts +0 -5
- package/dist/publish.d.ts.map +0 -1
- package/dist/publish.js +0 -40
- package/dist/publish.js.map +0 -1
- package/dist/registry.d.ts +0 -25
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -6
- package/dist/registry.js.map +0 -1
- package/dist/reload.d.ts +0 -126
- package/dist/reload.d.ts.map +0 -1
- package/dist/reload.js +0 -653
- package/dist/reload.js.map +0 -1
- package/dist/remote.d.ts +0 -165
- package/dist/remote.d.ts.map +0 -1
- package/dist/remote.js +0 -612
- package/dist/remote.js.map +0 -1
- package/dist/schema.d.ts +0 -21
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js +0 -228
- package/dist/schema.js.map +0 -1
- package/dist/state.d.ts +0 -92
- package/dist/state.d.ts.map +0 -1
- package/dist/state.js +0 -287
- package/dist/state.js.map +0 -1
- package/dist/types.d.ts +0 -88
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/websocket.d.ts +0 -15
- package/dist/websocket.d.ts.map +0 -1
- package/dist/websocket.js +0 -16
- package/dist/websocket.js.map +0 -1
- package/dist/wire.d.ts +0 -216
- package/dist/wire.d.ts.map +0 -1
- package/dist/wire.js +0 -165
- package/dist/wire.js.map +0 -1
- package/docs/guide.md +0 -814
- package/docs/spec.md +0 -288
- package/docs/tutorial.md +0 -931
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
// Session sync over a Chord store's outbox: upload the commits after the last sequence a copy shares with a remote
|
|
2
|
+
// into a slot the remote creates once, pull a copy forward with `applyBatch`, restore from an archive, fold history
|
|
3
|
+
// into snapshots, and decide when to upload. The remote and the host's sync state are interfaces (`remote.ts`).
|
|
4
|
+
//
|
|
5
|
+
// Bounded memory: bodies are streams (`batch.ts`). An upload reads the outbox a page at a time and stops a batch at
|
|
6
|
+
// `BATCH_BYTES`; a pull applies a batch in chunks of at most `APPLY_BYTES`; a snapshot is exported and imported as it
|
|
7
|
+
// streams. Nothing holds a whole batch, snapshot or store, so a Durable Object's isolate (128 MB) can run it.
|
|
8
|
+
import { applyBatch } from "../store/apply-batch.js";
|
|
9
|
+
import { importStore } from "../store/import.js";
|
|
10
|
+
import { openStore } from "../store/store.js";
|
|
11
|
+
import { decodeBatchLines, decodeSnapshot, encodeBatch, encodeSnapshot } from "./batch.js";
|
|
12
|
+
import { HistoryUnavailableError, LOG_START, remoteHead, remoteHistory, } from "./remote.js";
|
|
13
|
+
/** Commits read from the outbox per page at most. */
|
|
14
|
+
const OUTBOX_PAGE = 100;
|
|
15
|
+
/** About how much one outbox page holds: the count of the next page follows the size of the commits read. */
|
|
16
|
+
const PAGE_BYTES = 1024 * 1024;
|
|
17
|
+
/**
|
|
18
|
+
* Where an upload ends a batch: once its lines (before compression) reach this size. One commit larger than this is
|
|
19
|
+
* a batch of its own.
|
|
20
|
+
*/
|
|
21
|
+
export const BATCH_BYTES = 8 * 1024 * 1024;
|
|
22
|
+
/** How much of a batch a pull holds before it applies it: commits are applied in chunks of about this size. */
|
|
23
|
+
export const APPLY_BYTES = 4 * 1024 * 1024;
|
|
24
|
+
/** The last sequence a copy shares with the remote, counting commits an interrupted pull applied. */
|
|
25
|
+
function sharedHead(state, local) {
|
|
26
|
+
if (state?.pulling !== undefined && local <= state.pulling)
|
|
27
|
+
return local;
|
|
28
|
+
return state?.syncedHead ?? LOG_START;
|
|
29
|
+
}
|
|
30
|
+
/** A store's head as a sequence: `lastSeq`, 0 for a store without commits. */
|
|
31
|
+
export function storeHead(store) {
|
|
32
|
+
return store.lastSeq;
|
|
33
|
+
}
|
|
34
|
+
/** The store keeps no outbox, or its outbox no longer holds the commits a sync needs. */
|
|
35
|
+
export class OutboxUnavailableError extends Error {
|
|
36
|
+
constructor(message) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = "OutboxUnavailableError";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function outboxOf(store) {
|
|
42
|
+
if (store.outbox === undefined) {
|
|
43
|
+
throw new OutboxUnavailableError("The session's store has no outbox: open it with { outbox: true } to sync it");
|
|
44
|
+
}
|
|
45
|
+
return store.outbox;
|
|
46
|
+
}
|
|
47
|
+
/** The outbox commits after `after`, a page of at most `limit`. */
|
|
48
|
+
export async function readOutbox(store, after, limit, context) {
|
|
49
|
+
const outbox = outboxOf(store);
|
|
50
|
+
if (after < outbox.floor) {
|
|
51
|
+
throw new OutboxUnavailableError(`The outbox starts after ${outbox.floor}, past the synced head ${after}`);
|
|
52
|
+
}
|
|
53
|
+
return outbox.read(after, limit, context);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Upload what this copy committed since it last shared the remote's history, from the store's outbox, and trim the
|
|
57
|
+
* outbox through what the remote acknowledged. Every device continues a session as its own; whichever creates the slot
|
|
58
|
+
* first continues the session, so an upload that is acknowledged stays.
|
|
59
|
+
*
|
|
60
|
+
* A session the remote does not have yet, whose outbox does not reach back to its first commit (turned on later, or
|
|
61
|
+
* trimmed, as for a copy renamed after it diverged), starts with an archive slot: the store's `export()` at its head.
|
|
62
|
+
*
|
|
63
|
+
* A slot this device created already is an upload whose response was lost: the remote has the history up to its end,
|
|
64
|
+
* and the upload goes on from there.
|
|
65
|
+
*/
|
|
66
|
+
export async function uploadSession(options) {
|
|
67
|
+
const { sessionId, device, source, store, state, epoch, context } = options;
|
|
68
|
+
const outbox = outboxOf(source);
|
|
69
|
+
let synced = sharedHead(await state.get(sessionId, context), storeHead(source));
|
|
70
|
+
let uploaded;
|
|
71
|
+
while (true) {
|
|
72
|
+
// Read again on every pass: a slot this device already holds may end past what the copy still has.
|
|
73
|
+
const head = storeHead(source);
|
|
74
|
+
if (head < synced)
|
|
75
|
+
return { type: "behind", head, syncedHead: synced };
|
|
76
|
+
let to;
|
|
77
|
+
let body;
|
|
78
|
+
let archive = false;
|
|
79
|
+
let close;
|
|
80
|
+
if (synced === LOG_START && outbox.floor > 0) {
|
|
81
|
+
const snapshot = await exportSnapshot(source, context);
|
|
82
|
+
to = snapshot.to;
|
|
83
|
+
body = snapshot.body;
|
|
84
|
+
close = snapshot.close;
|
|
85
|
+
archive = true;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const range = await outboxRange(source, synced, context);
|
|
89
|
+
if (range === undefined)
|
|
90
|
+
return uploaded === undefined ? { type: "idle" } : { type: "uploaded", head: uploaded };
|
|
91
|
+
to = range.to;
|
|
92
|
+
body = encodeBatch(outboxCommits(source, synced, to, context));
|
|
93
|
+
}
|
|
94
|
+
const after = synced;
|
|
95
|
+
let result;
|
|
96
|
+
try {
|
|
97
|
+
result = await store.putBatch(sessionId, after, to, device, body, context, {
|
|
98
|
+
...(archive ? { archive } : {}),
|
|
99
|
+
...(epoch === undefined ? {} : { epoch }),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
// A remote that answered without reading the archive leaves the export holding the commit queue.
|
|
104
|
+
await close?.();
|
|
105
|
+
}
|
|
106
|
+
// A history that does not end at `after` is another one too: the remote never held this copy's past `after`.
|
|
107
|
+
if (result.type === "stale_epoch")
|
|
108
|
+
return { type: "stale_epoch", at: after, epoch: result.epoch };
|
|
109
|
+
if (result.type === "not_head")
|
|
110
|
+
return { type: "diverged", at: after };
|
|
111
|
+
if (result.type === "exists" && result.device !== device)
|
|
112
|
+
return { type: "diverged", at: after };
|
|
113
|
+
synced = result.type === "created" ? to : result.to;
|
|
114
|
+
await state.set(sessionId, { syncedHead: synced }, context);
|
|
115
|
+
const trimmable = Math.min(synced, source.lastSeq);
|
|
116
|
+
if (trimmable > outbox.floor)
|
|
117
|
+
await outbox.trim(trimmable, context);
|
|
118
|
+
if (result.type === "created")
|
|
119
|
+
uploaded = to;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Where the next batch after `after` ends: the outbox read a page at a time, holding one page, until the lines reach
|
|
124
|
+
* `BATCH_BYTES` (one commit at least). Undefined when the outbox has nothing after `after`.
|
|
125
|
+
*/
|
|
126
|
+
async function outboxRange(store, after, context) {
|
|
127
|
+
let to;
|
|
128
|
+
let bytes = 0;
|
|
129
|
+
const pages = new OutboxPages(store, after, context);
|
|
130
|
+
for (let page = await pages.next(); page.length > 0; page = await pages.next()) {
|
|
131
|
+
for (const commit of page) {
|
|
132
|
+
if (to !== undefined && bytes + encodedSize(commit) > BATCH_BYTES)
|
|
133
|
+
return { to };
|
|
134
|
+
bytes += encodedSize(commit);
|
|
135
|
+
to = commit.seq;
|
|
136
|
+
}
|
|
137
|
+
if (bytes >= BATCH_BYTES)
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
return to === undefined ? undefined : { to };
|
|
141
|
+
}
|
|
142
|
+
/** The outbox commits after `after` through `to`, a page at a time, as the body is read. */
|
|
143
|
+
async function* outboxCommits(store, after, to, context) {
|
|
144
|
+
const pages = new OutboxPages(store, after, context);
|
|
145
|
+
let at = after;
|
|
146
|
+
while (at < to) {
|
|
147
|
+
const page = await pages.next();
|
|
148
|
+
if (page.length === 0)
|
|
149
|
+
throw new OutboxUnavailableError(`The outbox ends at ${at}, before ${to}`);
|
|
150
|
+
for (const commit of page) {
|
|
151
|
+
if (commit.seq > to)
|
|
152
|
+
return;
|
|
153
|
+
yield commit;
|
|
154
|
+
at = commit.seq;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Pages of the outbox after a sequence, each about `PAGE_BYTES`: the outbox reads by count, so the next page's count
|
|
160
|
+
* follows the commits read so far (`OUTBOX_PAGE` to start, one commit at least). A run of large commits reads one at a
|
|
161
|
+
* time instead of `OUTBOX_PAGE` of them at once.
|
|
162
|
+
*/
|
|
163
|
+
class OutboxPages {
|
|
164
|
+
#store;
|
|
165
|
+
#context;
|
|
166
|
+
#after;
|
|
167
|
+
#limit = OUTBOX_PAGE;
|
|
168
|
+
#done = false;
|
|
169
|
+
constructor(store, after, context) {
|
|
170
|
+
this.#store = store;
|
|
171
|
+
this.#after = after;
|
|
172
|
+
this.#context = context;
|
|
173
|
+
}
|
|
174
|
+
async next() {
|
|
175
|
+
if (this.#done)
|
|
176
|
+
return [];
|
|
177
|
+
const page = await readOutbox(this.#store, this.#after, this.#limit, this.#context);
|
|
178
|
+
if (page.length < this.#limit)
|
|
179
|
+
this.#done = true;
|
|
180
|
+
if (page.length === 0)
|
|
181
|
+
return page;
|
|
182
|
+
this.#after = page.at(-1).seq;
|
|
183
|
+
const average = page.reduce((size, commit) => size + encodedSize(commit), 0) / page.length;
|
|
184
|
+
this.#limit = Math.max(1, Math.min(OUTBOX_PAGE, Math.floor(PAGE_BYTES / average)));
|
|
185
|
+
return page;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** A commit's line size before compression, as `BATCH_BYTES` counts it. */
|
|
189
|
+
function encodedSize(commit) {
|
|
190
|
+
return JSON.stringify(commit.writes).length + 64;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The store's state as a streamed snapshot body. The export holds the store's commit queue from its first part until
|
|
194
|
+
* the body is read to the end or `close()` is called, so `to` (its manifest's `lastSeq`) is exactly what it holds.
|
|
195
|
+
*/
|
|
196
|
+
async function exportSnapshot(store, context) {
|
|
197
|
+
const parts = store.export(context);
|
|
198
|
+
const first = await parts.next();
|
|
199
|
+
if (first.done || first.value.kind !== "manifest") {
|
|
200
|
+
await parts.return?.(undefined);
|
|
201
|
+
throw new Error("A store export does not start with its manifest");
|
|
202
|
+
}
|
|
203
|
+
const manifest = first.value;
|
|
204
|
+
return {
|
|
205
|
+
to: manifest.lastSeq,
|
|
206
|
+
body: encodeSnapshot((async function* () {
|
|
207
|
+
yield manifest;
|
|
208
|
+
yield* parts;
|
|
209
|
+
})()),
|
|
210
|
+
close: async () => {
|
|
211
|
+
await parts.return?.(undefined);
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Apply a batch body to `store` as it streams, in chunks of about `APPLY_BYTES`, skipping the commits the store has
|
|
217
|
+
* (a pull resuming inside a batch). Each chunk is one `applyBatch()` transaction; a pull stopped between chunks
|
|
218
|
+
* resumes after the last applied one.
|
|
219
|
+
*/
|
|
220
|
+
async function applyBody(store, body, context) {
|
|
221
|
+
let chunk = [];
|
|
222
|
+
let bytes = 0;
|
|
223
|
+
for await (const line of decodeBatchLines(body)) {
|
|
224
|
+
if (line.commit.seq <= store.lastSeq)
|
|
225
|
+
continue;
|
|
226
|
+
chunk.push(line.commit);
|
|
227
|
+
bytes += line.bytes;
|
|
228
|
+
if (bytes >= APPLY_BYTES) {
|
|
229
|
+
await applyBatch(store, chunk, context);
|
|
230
|
+
chunk = [];
|
|
231
|
+
bytes = 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (chunk.length > 0)
|
|
235
|
+
await applyBatch(store, chunk, context);
|
|
236
|
+
}
|
|
237
|
+
/** This copy has commits it has not uploaded: upload them first, which may find that the copy diverged. */
|
|
238
|
+
export class UnsyncedCommitsError extends Error {
|
|
239
|
+
constructor(sessionId, localHead, syncedHead) {
|
|
240
|
+
super(`This copy of session ${sessionId} is at ${localHead}, past what it shares with the remote (${syncedHead})`);
|
|
241
|
+
this.name = "UnsyncedCommitsError";
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Apply what the remote has after the local head; into an empty backend, that restores the session (from an archive
|
|
246
|
+
* when the history starts with one) and opens its store with an outbox. Resolves with the store, which the caller
|
|
247
|
+
* owns and closes. Nothing may hold the store's claims (no `StoreStorage`, no Harness): `applyBatch()` refuses then.
|
|
248
|
+
*
|
|
249
|
+
* A copy with commits it has not uploaded rejects with `UnsyncedCommitsError` instead of getting the remote's commits
|
|
250
|
+
* spliced onto its own. A copy whose history folding removed rejects with `HistoryUnavailableError` and restores into
|
|
251
|
+
* a fresh backend.
|
|
252
|
+
*/
|
|
253
|
+
export async function pullSession(options) {
|
|
254
|
+
const { sessionId, store: remote, local, state, context } = options;
|
|
255
|
+
const listing = await remote.list(sessionId, context);
|
|
256
|
+
let target = local.kind === "store" ? local.store : undefined;
|
|
257
|
+
const at = () => (target === undefined ? LOG_START : storeHead(target));
|
|
258
|
+
const synced = sharedHead(await state.get(sessionId, context), at());
|
|
259
|
+
if (at() > synced)
|
|
260
|
+
throw new UnsyncedCommitsError(sessionId, at(), synced);
|
|
261
|
+
const history = remoteHistory(listing, at());
|
|
262
|
+
try {
|
|
263
|
+
const bodies = [];
|
|
264
|
+
if (history.snapshot !== undefined) {
|
|
265
|
+
const snapshot = history.snapshot;
|
|
266
|
+
bodies.push({ to: snapshot, archive: true, read: () => remote.getSnapshot(sessionId, snapshot, context) });
|
|
267
|
+
}
|
|
268
|
+
for (const batch of history.batches) {
|
|
269
|
+
bodies.push({
|
|
270
|
+
to: batch.to,
|
|
271
|
+
archive: batch.archive === true,
|
|
272
|
+
read: () => remote.getBatch(sessionId, batch.after, context),
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
for (const body of bodies) {
|
|
276
|
+
if (body.to <= at())
|
|
277
|
+
continue;
|
|
278
|
+
const bytes = await body.read();
|
|
279
|
+
if (bytes === undefined)
|
|
280
|
+
throw new HistoryUnavailableError(at());
|
|
281
|
+
await state.set(sessionId, { syncedHead: at(), pulling: body.to }, context);
|
|
282
|
+
if (body.archive) {
|
|
283
|
+
// An archive restores a whole store: only into an empty backend.
|
|
284
|
+
if (target !== undefined || local.kind !== "empty")
|
|
285
|
+
throw new HistoryUnavailableError(at());
|
|
286
|
+
target = await importStore(local.backend, decodeSnapshot(bytes), context, { outbox: true });
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
if (target === undefined) {
|
|
290
|
+
if (local.kind !== "empty")
|
|
291
|
+
throw new Error("unreachable: a store copy always has a target");
|
|
292
|
+
target = await openStore(local.backend, context, { outbox: true });
|
|
293
|
+
}
|
|
294
|
+
await applyBody(target, bytes, context);
|
|
295
|
+
}
|
|
296
|
+
await state.set(sessionId, { syncedHead: at() }, context);
|
|
297
|
+
}
|
|
298
|
+
if (target === undefined) {
|
|
299
|
+
if (local.kind !== "empty")
|
|
300
|
+
throw new Error("unreachable: a store copy always has a target");
|
|
301
|
+
target = await openStore(local.backend, context, { outbox: true });
|
|
302
|
+
}
|
|
303
|
+
const head = at();
|
|
304
|
+
if (head < remoteHead(listing))
|
|
305
|
+
throw new HistoryUnavailableError(head);
|
|
306
|
+
await state.set(sessionId, { syncedHead: head }, context);
|
|
307
|
+
// What the remote holds needs no upload: the outbox keeps only this copy's own commits.
|
|
308
|
+
const outbox = target.outbox;
|
|
309
|
+
if (outbox !== undefined && head > outbox.floor)
|
|
310
|
+
await outbox.trim(head, context);
|
|
311
|
+
return { store: target, head };
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
// A store this pull opened is the caller's only on success.
|
|
315
|
+
if (local.kind === "empty" && target !== undefined)
|
|
316
|
+
await target.close(context).catch(() => { });
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Fold a session's history into one snapshot: restore it into `scratch` (an empty backend; a file or a Durable Object's
|
|
322
|
+
* SQLite storage, not `:memory:`, so the restored store is not held in memory), upload its `export()` as a snapshot, drop the commits of the batches it covers, keeping their
|
|
323
|
+
* slots taken, and delete older snapshots. The remote runs this, not clients.
|
|
324
|
+
*/
|
|
325
|
+
export async function foldSession(options) {
|
|
326
|
+
const { sessionId, store, scratch, context } = options;
|
|
327
|
+
const listing = await store.list(sessionId, context);
|
|
328
|
+
const history = remoteHistory(listing);
|
|
329
|
+
if (history.batches.length + (history.snapshot === undefined ? 0 : 1) < 2)
|
|
330
|
+
return undefined;
|
|
331
|
+
const restored = await pullSession({
|
|
332
|
+
sessionId,
|
|
333
|
+
store,
|
|
334
|
+
local: { kind: "empty", backend: scratch },
|
|
335
|
+
state: new ScratchState(),
|
|
336
|
+
context,
|
|
337
|
+
});
|
|
338
|
+
try {
|
|
339
|
+
const snapshot = await exportSnapshot(restored.store, context);
|
|
340
|
+
try {
|
|
341
|
+
await store.putSnapshot(sessionId, snapshot.to, snapshot.body, context);
|
|
342
|
+
}
|
|
343
|
+
finally {
|
|
344
|
+
await snapshot.close();
|
|
345
|
+
}
|
|
346
|
+
await store.foldBatches(sessionId, history.batches.filter((batch) => batch.to <= snapshot.to).map((batch) => batch.after), context);
|
|
347
|
+
await store.deleteSnapshots(sessionId, listing.snapshots.filter((at) => at < snapshot.to), context);
|
|
348
|
+
return snapshot.to;
|
|
349
|
+
}
|
|
350
|
+
finally {
|
|
351
|
+
await restored.store.close(context);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/** Sync state for a restore nobody continues. */
|
|
355
|
+
class ScratchState {
|
|
356
|
+
#state;
|
|
357
|
+
async get() {
|
|
358
|
+
return this.#state;
|
|
359
|
+
}
|
|
360
|
+
async set(_sessionId, state) {
|
|
361
|
+
this.#state = state;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Decides when to flush: some time after a commit, sooner after an urgent one, one flush at a time. Commits that arrive
|
|
366
|
+
* during a flush keep their urgency and schedule the next one when it ends. A failed flush is retried with backoff
|
|
367
|
+
* until one succeeds, so the last commits of a turn do not wait for the next commit.
|
|
368
|
+
*/
|
|
369
|
+
export class FlushScheduler {
|
|
370
|
+
#options;
|
|
371
|
+
#due;
|
|
372
|
+
#disarm;
|
|
373
|
+
#running;
|
|
374
|
+
/** When the commits that arrived during a flush want the next one. */
|
|
375
|
+
#pendingDue;
|
|
376
|
+
#failures = 0;
|
|
377
|
+
#closed = false;
|
|
378
|
+
constructor(options) {
|
|
379
|
+
this.#options = options;
|
|
380
|
+
}
|
|
381
|
+
/** A commit landed. */
|
|
382
|
+
notify(urgent) {
|
|
383
|
+
if (this.#closed)
|
|
384
|
+
return;
|
|
385
|
+
const due = this.#options.now() + (urgent ? (this.#options.urgentMs ?? 200) : (this.#options.intervalMs ?? 5000));
|
|
386
|
+
if (this.#running !== undefined) {
|
|
387
|
+
this.#pendingDue = Math.min(this.#pendingDue ?? due, due);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
this.#arm(due);
|
|
391
|
+
}
|
|
392
|
+
/** Flush now, after a flush underway, and stop scheduling. A failure rejects. */
|
|
393
|
+
async close() {
|
|
394
|
+
this.#closed = true;
|
|
395
|
+
this.#disarm?.();
|
|
396
|
+
this.#disarm = undefined;
|
|
397
|
+
this.#due = undefined;
|
|
398
|
+
await this.#running;
|
|
399
|
+
await this.#options.flush();
|
|
400
|
+
}
|
|
401
|
+
#arm(due) {
|
|
402
|
+
if (this.#due !== undefined && this.#due <= due)
|
|
403
|
+
return;
|
|
404
|
+
this.#disarm?.();
|
|
405
|
+
this.#due = due;
|
|
406
|
+
this.#disarm = this.#options.setTimer(() => void this.#run(), Math.max(0, due - this.#options.now()));
|
|
407
|
+
}
|
|
408
|
+
#run() {
|
|
409
|
+
this.#disarm = undefined;
|
|
410
|
+
this.#due = undefined;
|
|
411
|
+
this.#running = (async () => {
|
|
412
|
+
let retry;
|
|
413
|
+
try {
|
|
414
|
+
await this.#options.flush();
|
|
415
|
+
this.#failures = 0;
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
this.#options.onError(error);
|
|
419
|
+
const delay = (this.#options.retryMs ?? 1000) * 2 ** this.#failures;
|
|
420
|
+
this.#failures++;
|
|
421
|
+
retry = this.#options.now() + Math.min(delay, this.#options.maxRetryMs ?? 60_000);
|
|
422
|
+
}
|
|
423
|
+
finally {
|
|
424
|
+
this.#running = undefined;
|
|
425
|
+
}
|
|
426
|
+
if (this.#closed)
|
|
427
|
+
return;
|
|
428
|
+
const pending = this.#pendingDue;
|
|
429
|
+
this.#pendingDue = undefined;
|
|
430
|
+
// A retry waits for its backoff even when commits arrived: they flush with it.
|
|
431
|
+
const due = retry ?? pending;
|
|
432
|
+
if (due !== undefined)
|
|
433
|
+
this.#arm(due);
|
|
434
|
+
})();
|
|
435
|
+
return this.#running;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/sync/client.ts"],"names":[],"mappings":"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","sourcesContent":["// Session sync over a Chord store's outbox: upload the commits after the last sequence a copy shares with a remote\n// into a slot the remote creates once, pull a copy forward with `applyBatch`, restore from an archive, fold history\n// into snapshots, and decide when to upload. The remote and the host's sync state are interfaces (`remote.ts`).\n//\n// Bounded memory: bodies are streams (`batch.ts`). An upload reads the outbox a page at a time and stops a batch at\n// `BATCH_BYTES`; a pull applies a batch in chunks of at most `APPLY_BYTES`; a snapshot is exported and imported as it\n// streams. Nothing holds a whole batch, snapshot or store, so a Durable Object's isolate (128 MB) can run it.\n\nimport type { Context } from \"../context/index.ts\";\nimport { applyBatch } from \"../store/apply-batch.ts\";\nimport type { Backend } from \"../store/backend.ts\";\nimport { importStore } from \"../store/import.ts\";\nimport type { OutboxCommit } from \"../store/outbox.ts\";\nimport { type ChordStore, openStore, type Store } from \"../store/store.ts\";\nimport { decodeBatchLines, decodeSnapshot, encodeBatch, encodeSnapshot, type SyncBody } from \"./batch.ts\";\nimport {\n\ttype BatchInfo,\n\tHistoryUnavailableError,\n\tLOG_START,\n\ttype PutBatchResult,\n\tremoteHead,\n\tremoteHistory,\n\ttype Seq,\n\ttype SessionSyncMaintenance,\n\ttype SessionSyncStore,\n} from \"./remote.ts\";\n\n/** Commits read from the outbox per page at most. */\nconst OUTBOX_PAGE = 100;\n/** About how much one outbox page holds: the count of the next page follows the size of the commits read. */\nconst PAGE_BYTES = 1024 * 1024;\n/**\n * Where an upload ends a batch: once its lines (before compression) reach this size. One commit larger than this is\n * a batch of its own.\n */\nexport const BATCH_BYTES = 8 * 1024 * 1024;\n/** How much of a batch a pull holds before it applies it: commits are applied in chunks of about this size. */\nexport const APPLY_BYTES = 4 * 1024 * 1024;\n\n/**\n * What a host keeps for each copy of a session it syncs: the last sequence the copy shares with the remote. Commits\n * after it are the copy's own and not uploaded yet. When this is lost, a copy without commits of its own takes the\n * remote's head; one with commits finds out by uploading.\n */\nexport type SyncState = {\n\treadonly syncedHead: Seq | undefined;\n\t/**\n\t * Set while a pull applies a batch or snapshot ending here: a local head up to it holds the remote's commits, not\n\t * the copy's own, even when the pull stopped partway.\n\t */\n\treadonly pulling?: Seq;\n};\n\n/** The last sequence a copy shares with the remote, counting commits an interrupted pull applied. */\nfunction sharedHead(state: SyncState | undefined, local: Seq): Seq {\n\tif (state?.pulling !== undefined && local <= state.pulling) return local;\n\treturn state?.syncedHead ?? LOG_START;\n}\n\nexport interface SyncStateStore {\n\tget(sessionId: string, context: Context): Promise<SyncState | undefined>;\n\tset(sessionId: string, state: SyncState, context: Context): Promise<void>;\n}\n\n/** A store's head as a sequence: `lastSeq`, 0 for a store without commits. */\nexport function storeHead(store: Store): Seq {\n\treturn store.lastSeq;\n}\n\n/** The store keeps no outbox, or its outbox no longer holds the commits a sync needs. */\nexport class OutboxUnavailableError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"OutboxUnavailableError\";\n\t}\n}\n\nfunction outboxOf(store: Store) {\n\tif (store.outbox === undefined) {\n\t\tthrow new OutboxUnavailableError(\"The session's store has no outbox: open it with { outbox: true } to sync it\");\n\t}\n\treturn store.outbox;\n}\n\n/** The outbox commits after `after`, a page of at most `limit`. */\nexport async function readOutbox(store: Store, after: Seq, limit: number, context: Context): Promise<OutboxCommit[]> {\n\tconst outbox = outboxOf(store);\n\tif (after < outbox.floor) {\n\t\tthrow new OutboxUnavailableError(`The outbox starts after ${outbox.floor}, past the synced head ${after}`);\n\t}\n\treturn outbox.read(after, limit, context);\n}\n\nexport type UploadResult =\n\t| { readonly type: \"uploaded\"; readonly head: Seq }\n\t/** Nothing was committed since the last upload. */\n\t| { readonly type: \"idle\" }\n\t/**\n\t * Another device continued the session from `at` first. This copy's commits after `at` are a different history:\n\t * the host renames the copy to a new session (forked from this one at `at`) and uploads it there, and the session\n\t * itself restores into a fresh store.\n\t */\n\t| { readonly type: \"diverged\"; readonly at: Seq }\n\t/**\n\t * The copy lost commits it had uploaded, for example to a power loss: its head is below `syncedHead`. Its next\n\t * commits would reuse their sequences, so nothing is uploaded. Pull what it lost before the copy commits again; a pull\n\t * applies from the local head.\n\t */\n\t| { readonly type: \"behind\"; readonly head: Seq; readonly syncedHead: Seq }\n\t/**\n\t * The remote refused this device's epoch: another device holds the right to write the session now. Like\n\t * `diverged`, the copy's commits after `at` are a different history, so the host forks the copy (S7).\n\t */\n\t| { readonly type: \"stale_epoch\"; readonly at: Seq; readonly epoch: number };\n\n/**\n * Upload what this copy committed since it last shared the remote's history, from the store's outbox, and trim the\n * outbox through what the remote acknowledged. Every device continues a session as its own; whichever creates the slot\n * first continues the session, so an upload that is acknowledged stays.\n *\n * A session the remote does not have yet, whose outbox does not reach back to its first commit (turned on later, or\n * trimmed, as for a copy renamed after it diverged), starts with an archive slot: the store's `export()` at its head.\n *\n * A slot this device created already is an upload whose response was lost: the remote has the history up to its end,\n * and the upload goes on from there.\n */\nexport async function uploadSession(options: {\n\treadonly sessionId: string;\n\treadonly device: string;\n\treadonly source: Store;\n\treadonly store: SessionSyncStore;\n\treadonly state: SyncStateStore;\n\t/** The writer's epoch, from whatever grants it (the remote, Radius); sent with every slot. */\n\treadonly epoch?: number;\n\treadonly context: Context;\n}): Promise<UploadResult> {\n\tconst { sessionId, device, source, store, state, epoch, context } = options;\n\tconst outbox = outboxOf(source);\n\tlet synced = sharedHead(await state.get(sessionId, context), storeHead(source));\n\tlet uploaded: Seq | undefined;\n\twhile (true) {\n\t\t// Read again on every pass: a slot this device already holds may end past what the copy still has.\n\t\tconst head = storeHead(source);\n\t\tif (head < synced) return { type: \"behind\", head, syncedHead: synced };\n\t\tlet to: Seq;\n\t\tlet body: SyncBody;\n\t\tlet archive = false;\n\t\tlet close: (() => Promise<void>) | undefined;\n\t\tif (synced === LOG_START && outbox.floor > 0) {\n\t\t\tconst snapshot = await exportSnapshot(source, context);\n\t\t\tto = snapshot.to;\n\t\t\tbody = snapshot.body;\n\t\t\tclose = snapshot.close;\n\t\t\tarchive = true;\n\t\t} else {\n\t\t\tconst range = await outboxRange(source, synced, context);\n\t\t\tif (range === undefined)\n\t\t\t\treturn uploaded === undefined ? { type: \"idle\" } : { type: \"uploaded\", head: uploaded };\n\t\t\tto = range.to;\n\t\t\tbody = encodeBatch(outboxCommits(source, synced, to, context));\n\t\t}\n\t\tconst after = synced;\n\t\tlet result: PutBatchResult;\n\t\ttry {\n\t\t\tresult = await store.putBatch(sessionId, after, to, device, body, context, {\n\t\t\t\t...(archive ? { archive } : {}),\n\t\t\t\t...(epoch === undefined ? {} : { epoch }),\n\t\t\t});\n\t\t} finally {\n\t\t\t// A remote that answered without reading the archive leaves the export holding the commit queue.\n\t\t\tawait close?.();\n\t\t}\n\t\t// A history that does not end at `after` is another one too: the remote never held this copy's past `after`.\n\t\tif (result.type === \"stale_epoch\") return { type: \"stale_epoch\", at: after, epoch: result.epoch };\n\t\tif (result.type === \"not_head\") return { type: \"diverged\", at: after };\n\t\tif (result.type === \"exists\" && result.device !== device) return { type: \"diverged\", at: after };\n\t\tsynced = result.type === \"created\" ? to : result.to;\n\t\tawait state.set(sessionId, { syncedHead: synced }, context);\n\t\tconst trimmable = Math.min(synced, source.lastSeq);\n\t\tif (trimmable > outbox.floor) await outbox.trim(trimmable, context);\n\t\tif (result.type === \"created\") uploaded = to;\n\t}\n}\n\n/**\n * Where the next batch after `after` ends: the outbox read a page at a time, holding one page, until the lines reach\n * `BATCH_BYTES` (one commit at least). Undefined when the outbox has nothing after `after`.\n */\nasync function outboxRange(store: Store, after: Seq, context: Context): Promise<{ readonly to: Seq } | undefined> {\n\tlet to: Seq | undefined;\n\tlet bytes = 0;\n\tconst pages = new OutboxPages(store, after, context);\n\tfor (let page = await pages.next(); page.length > 0; page = await pages.next()) {\n\t\tfor (const commit of page) {\n\t\t\tif (to !== undefined && bytes + encodedSize(commit) > BATCH_BYTES) return { to };\n\t\t\tbytes += encodedSize(commit);\n\t\t\tto = commit.seq;\n\t\t}\n\t\tif (bytes >= BATCH_BYTES) break;\n\t}\n\treturn to === undefined ? undefined : { to };\n}\n\n/** The outbox commits after `after` through `to`, a page at a time, as the body is read. */\nasync function* outboxCommits(store: Store, after: Seq, to: Seq, context: Context): AsyncGenerator<OutboxCommit> {\n\tconst pages = new OutboxPages(store, after, context);\n\tlet at = after;\n\twhile (at < to) {\n\t\tconst page = await pages.next();\n\t\tif (page.length === 0) throw new OutboxUnavailableError(`The outbox ends at ${at}, before ${to}`);\n\t\tfor (const commit of page) {\n\t\t\tif (commit.seq > to) return;\n\t\t\tyield commit;\n\t\t\tat = commit.seq;\n\t\t}\n\t}\n}\n\n/**\n * Pages of the outbox after a sequence, each about `PAGE_BYTES`: the outbox reads by count, so the next page's count\n * follows the commits read so far (`OUTBOX_PAGE` to start, one commit at least). A run of large commits reads one at a\n * time instead of `OUTBOX_PAGE` of them at once.\n */\nclass OutboxPages {\n\treadonly #store: Store;\n\treadonly #context: Context;\n\t#after: Seq;\n\t#limit = OUTBOX_PAGE;\n\t#done = false;\n\n\tconstructor(store: Store, after: Seq, context: Context) {\n\t\tthis.#store = store;\n\t\tthis.#after = after;\n\t\tthis.#context = context;\n\t}\n\n\tasync next(): Promise<OutboxCommit[]> {\n\t\tif (this.#done) return [];\n\t\tconst page = await readOutbox(this.#store, this.#after, this.#limit, this.#context);\n\t\tif (page.length < this.#limit) this.#done = true;\n\t\tif (page.length === 0) return page;\n\t\tthis.#after = page.at(-1)!.seq;\n\t\tconst average = page.reduce((size, commit) => size + encodedSize(commit), 0) / page.length;\n\t\tthis.#limit = Math.max(1, Math.min(OUTBOX_PAGE, Math.floor(PAGE_BYTES / average)));\n\t\treturn page;\n\t}\n}\n\n/** A commit's line size before compression, as `BATCH_BYTES` counts it. */\nfunction encodedSize(commit: OutboxCommit): number {\n\treturn JSON.stringify(commit.writes).length + 64;\n}\n\n/** A snapshot of a store being exported: where it ends, its body, and `close()` for when the body is not read to the end. */\ntype ExportedSnapshot = { readonly to: Seq; readonly body: SyncBody; close(): Promise<void> };\n\n/**\n * The store's state as a streamed snapshot body. The export holds the store's commit queue from its first part until\n * the body is read to the end or `close()` is called, so `to` (its manifest's `lastSeq`) is exactly what it holds.\n */\nasync function exportSnapshot(store: Store, context: Context): Promise<ExportedSnapshot> {\n\tconst parts = store.export(context);\n\tconst first = await parts.next();\n\tif (first.done || first.value.kind !== \"manifest\") {\n\t\tawait parts.return?.(undefined);\n\t\tthrow new Error(\"A store export does not start with its manifest\");\n\t}\n\tconst manifest = first.value;\n\treturn {\n\t\tto: manifest.lastSeq,\n\t\tbody: encodeSnapshot(\n\t\t\t(async function* () {\n\t\t\t\tyield manifest;\n\t\t\t\tyield* parts;\n\t\t\t})(),\n\t\t),\n\t\tclose: async () => {\n\t\t\tawait parts.return?.(undefined);\n\t\t},\n\t};\n}\n\n/**\n * Apply a batch body to `store` as it streams, in chunks of about `APPLY_BYTES`, skipping the commits the store has\n * (a pull resuming inside a batch). Each chunk is one `applyBatch()` transaction; a pull stopped between chunks\n * resumes after the last applied one.\n */\nasync function applyBody(store: ChordStore, body: SyncBody, context: Context): Promise<void> {\n\tlet chunk: OutboxCommit[] = [];\n\tlet bytes = 0;\n\tfor await (const line of decodeBatchLines(body)) {\n\t\tif (line.commit.seq <= store.lastSeq) continue;\n\t\tchunk.push(line.commit);\n\t\tbytes += line.bytes;\n\t\tif (bytes >= APPLY_BYTES) {\n\t\t\tawait applyBatch(store, chunk, context);\n\t\t\tchunk = [];\n\t\t\tbytes = 0;\n\t\t}\n\t}\n\tif (chunk.length > 0) await applyBatch(store, chunk, context);\n}\n\n/** This copy has commits it has not uploaded: upload them first, which may find that the copy diverged. */\nexport class UnsyncedCommitsError extends Error {\n\tconstructor(sessionId: string, localHead: Seq, syncedHead: Seq) {\n\t\tsuper(\n\t\t\t`This copy of session ${sessionId} is at ${localHead}, past what it shares with the remote (${syncedHead})`,\n\t\t);\n\t\tthis.name = \"UnsyncedCommitsError\";\n\t}\n}\n\n/** The copy a pull applies to: an open store, or an empty backend to restore the session into. */\nexport type LocalCopy =\n\t| { readonly kind: \"store\"; readonly store: Store }\n\t| { readonly kind: \"empty\"; readonly backend: Backend };\n\n/**\n * Apply what the remote has after the local head; into an empty backend, that restores the session (from an archive\n * when the history starts with one) and opens its store with an outbox. Resolves with the store, which the caller\n * owns and closes. Nothing may hold the store's claims (no `StoreStorage`, no Harness): `applyBatch()` refuses then.\n *\n * A copy with commits it has not uploaded rejects with `UnsyncedCommitsError` instead of getting the remote's commits\n * spliced onto its own. A copy whose history folding removed rejects with `HistoryUnavailableError` and restores into\n * a fresh backend.\n */\nexport async function pullSession(options: {\n\treadonly sessionId: string;\n\treadonly store: SessionSyncStore;\n\treadonly local: LocalCopy;\n\treadonly state: SyncStateStore;\n\treadonly context: Context;\n}): Promise<{ readonly store: Store; readonly head: Seq }> {\n\tconst { sessionId, store: remote, local, state, context } = options;\n\tconst listing = await remote.list(sessionId, context);\n\tlet target: Store | undefined = local.kind === \"store\" ? local.store : undefined;\n\tconst at = () => (target === undefined ? LOG_START : storeHead(target));\n\tconst synced = sharedHead(await state.get(sessionId, context), at());\n\tif (at() > synced) throw new UnsyncedCommitsError(sessionId, at(), synced);\n\tconst history = remoteHistory(listing, at());\n\ttry {\n\t\tconst bodies: { readonly to: Seq; readonly archive: boolean; read(): Promise<SyncBody | undefined> }[] = [];\n\t\tif (history.snapshot !== undefined) {\n\t\t\tconst snapshot = history.snapshot;\n\t\t\tbodies.push({ to: snapshot, archive: true, read: () => remote.getSnapshot(sessionId, snapshot, context) });\n\t\t}\n\t\tfor (const batch of history.batches) {\n\t\t\tbodies.push({\n\t\t\t\tto: batch.to,\n\t\t\t\tarchive: batch.archive === true,\n\t\t\t\tread: () => remote.getBatch(sessionId, batch.after, context),\n\t\t\t});\n\t\t}\n\t\tfor (const body of bodies) {\n\t\t\tif (body.to <= at()) continue;\n\t\t\tconst bytes = await body.read();\n\t\t\tif (bytes === undefined) throw new HistoryUnavailableError(at());\n\t\t\tawait state.set(sessionId, { syncedHead: at(), pulling: body.to }, context);\n\t\t\tif (body.archive) {\n\t\t\t\t// An archive restores a whole store: only into an empty backend.\n\t\t\t\tif (target !== undefined || local.kind !== \"empty\") throw new HistoryUnavailableError(at());\n\t\t\t\ttarget = await importStore(local.backend, decodeSnapshot(bytes), context, { outbox: true });\n\t\t\t} else {\n\t\t\t\tif (target === undefined) {\n\t\t\t\t\tif (local.kind !== \"empty\") throw new Error(\"unreachable: a store copy always has a target\");\n\t\t\t\t\ttarget = await openStore(local.backend, context, { outbox: true });\n\t\t\t\t}\n\t\t\t\tawait applyBody(target as ChordStore, bytes, context);\n\t\t\t}\n\t\t\tawait state.set(sessionId, { syncedHead: at() }, context);\n\t\t}\n\t\tif (target === undefined) {\n\t\t\tif (local.kind !== \"empty\") throw new Error(\"unreachable: a store copy always has a target\");\n\t\t\ttarget = await openStore(local.backend, context, { outbox: true });\n\t\t}\n\t\tconst head = at();\n\t\tif (head < remoteHead(listing)) throw new HistoryUnavailableError(head);\n\t\tawait state.set(sessionId, { syncedHead: head }, context);\n\t\t// What the remote holds needs no upload: the outbox keeps only this copy's own commits.\n\t\tconst outbox = target.outbox;\n\t\tif (outbox !== undefined && head > outbox.floor) await outbox.trim(head, context);\n\t\treturn { store: target, head };\n\t} catch (error) {\n\t\t// A store this pull opened is the caller's only on success.\n\t\tif (local.kind === \"empty\" && target !== undefined) await target.close(context).catch(() => {});\n\t\tthrow error;\n\t}\n}\n\n/**\n * Fold a session's history into one snapshot: restore it into `scratch` (an empty backend; a file or a Durable Object's\n * SQLite storage, not `:memory:`, so the restored store is not held in memory), upload its `export()` as a snapshot, drop the commits of the batches it covers, keeping their\n * slots taken, and delete older snapshots. The remote runs this, not clients.\n */\nexport async function foldSession(options: {\n\treadonly sessionId: string;\n\treadonly store: SessionSyncMaintenance;\n\treadonly scratch: Backend;\n\treadonly context: Context;\n}): Promise<Seq | undefined> {\n\tconst { sessionId, store, scratch, context } = options;\n\tconst listing = await store.list(sessionId, context);\n\tconst history = remoteHistory(listing);\n\tif (history.batches.length + (history.snapshot === undefined ? 0 : 1) < 2) return undefined;\n\tconst restored = await pullSession({\n\t\tsessionId,\n\t\tstore,\n\t\tlocal: { kind: \"empty\", backend: scratch },\n\t\tstate: new ScratchState(),\n\t\tcontext,\n\t});\n\ttry {\n\t\tconst snapshot = await exportSnapshot(restored.store, context);\n\t\ttry {\n\t\t\tawait store.putSnapshot(sessionId, snapshot.to, snapshot.body, context);\n\t\t} finally {\n\t\t\tawait snapshot.close();\n\t\t}\n\t\tawait store.foldBatches(\n\t\t\tsessionId,\n\t\t\thistory.batches.filter((batch: BatchInfo) => batch.to <= snapshot.to).map((batch) => batch.after),\n\t\t\tcontext,\n\t\t);\n\t\tawait store.deleteSnapshots(\n\t\t\tsessionId,\n\t\t\tlisting.snapshots.filter((at) => at < snapshot.to),\n\t\t\tcontext,\n\t\t);\n\t\treturn snapshot.to;\n\t} finally {\n\t\tawait restored.store.close(context);\n\t}\n}\n\n/** Sync state for a restore nobody continues. */\nclass ScratchState implements SyncStateStore {\n\t#state: SyncState | undefined;\n\tasync get(): Promise<SyncState | undefined> {\n\t\treturn this.#state;\n\t}\n\tasync set(_sessionId: string, state: SyncState): Promise<void> {\n\t\tthis.#state = state;\n\t}\n}\n\nexport type FlushSchedulerOptions = {\n\treadonly flush: () => Promise<unknown>;\n\t/** Arms a timer and returns its disarm. */\n\treadonly setTimer: (callback: () => void, delayMs: number) => () => void;\n\treadonly now: () => number;\n\t/** A failed flush; the scheduler retries it with backoff. */\n\treadonly onError: (error: unknown) => void;\n\t/** Delay of an ordinary flush after a commit. Default 5 seconds. */\n\treadonly intervalMs?: number;\n\t/** Delay of a flush after an urgent commit. Default 200 milliseconds. */\n\treadonly urgentMs?: number;\n\t/** First retry delay after a failed flush, doubling up to `maxRetryMs`. Default 1 second. */\n\treadonly retryMs?: number;\n\t/** Default 1 minute. */\n\treadonly maxRetryMs?: number;\n};\n\n/**\n * Decides when to flush: some time after a commit, sooner after an urgent one, one flush at a time. Commits that arrive\n * during a flush keep their urgency and schedule the next one when it ends. A failed flush is retried with backoff\n * until one succeeds, so the last commits of a turn do not wait for the next commit.\n */\nexport class FlushScheduler {\n\treadonly #options: FlushSchedulerOptions;\n\t#due: number | undefined;\n\t#disarm: (() => void) | undefined;\n\t#running: Promise<void> | undefined;\n\t/** When the commits that arrived during a flush want the next one. */\n\t#pendingDue: number | undefined;\n\t#failures = 0;\n\t#closed = false;\n\n\tconstructor(options: FlushSchedulerOptions) {\n\t\tthis.#options = options;\n\t}\n\n\t/** A commit landed. */\n\tnotify(urgent: boolean): void {\n\t\tif (this.#closed) return;\n\t\tconst due = this.#options.now() + (urgent ? (this.#options.urgentMs ?? 200) : (this.#options.intervalMs ?? 5000));\n\t\tif (this.#running !== undefined) {\n\t\t\tthis.#pendingDue = Math.min(this.#pendingDue ?? due, due);\n\t\t\treturn;\n\t\t}\n\t\tthis.#arm(due);\n\t}\n\n\t/** Flush now, after a flush underway, and stop scheduling. A failure rejects. */\n\tasync close(): Promise<void> {\n\t\tthis.#closed = true;\n\t\tthis.#disarm?.();\n\t\tthis.#disarm = undefined;\n\t\tthis.#due = undefined;\n\t\tawait this.#running;\n\t\tawait this.#options.flush();\n\t}\n\n\t#arm(due: number): void {\n\t\tif (this.#due !== undefined && this.#due <= due) return;\n\t\tthis.#disarm?.();\n\t\tthis.#due = due;\n\t\tthis.#disarm = this.#options.setTimer(() => void this.#run(), Math.max(0, due - this.#options.now()));\n\t}\n\n\t#run(): Promise<void> {\n\t\tthis.#disarm = undefined;\n\t\tthis.#due = undefined;\n\t\tthis.#running = (async () => {\n\t\t\tlet retry: number | undefined;\n\t\t\ttry {\n\t\t\t\tawait this.#options.flush();\n\t\t\t\tthis.#failures = 0;\n\t\t\t} catch (error) {\n\t\t\t\tthis.#options.onError(error);\n\t\t\t\tconst delay = (this.#options.retryMs ?? 1000) * 2 ** this.#failures;\n\t\t\t\tthis.#failures++;\n\t\t\t\tretry = this.#options.now() + Math.min(delay, this.#options.maxRetryMs ?? 60_000);\n\t\t\t} finally {\n\t\t\t\tthis.#running = undefined;\n\t\t\t}\n\t\t\tif (this.#closed) return;\n\t\t\tconst pending = this.#pendingDue;\n\t\t\tthis.#pendingDue = undefined;\n\t\t\t// A retry waits for its backoff even when commits arrived: they flush with it.\n\t\t\tconst due = retry ?? pending;\n\t\t\tif (due !== undefined) this.#arm(due);\n\t\t})();\n\t\treturn this.#running;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Context } from "../context/index.ts";
|
|
2
|
+
/** An operation's outcome: its value, or the error it failed with. */
|
|
3
|
+
export type FileResult<T> = {
|
|
4
|
+
readonly ok: true;
|
|
5
|
+
readonly value: T;
|
|
6
|
+
} | {
|
|
7
|
+
readonly ok: false;
|
|
8
|
+
readonly error: Error;
|
|
9
|
+
};
|
|
10
|
+
/** A directory entry. */
|
|
11
|
+
export type SyncFileInfo = {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly kind: "file" | "directory" | "symlink";
|
|
14
|
+
};
|
|
15
|
+
/** A file opened for reads at offsets: what streaming a body back needs. */
|
|
16
|
+
export interface SyncFileReader {
|
|
17
|
+
/** Up to `length` bytes at `offset`; fewer only at end of file. */
|
|
18
|
+
read(offset: number, length: number, context: Context): Promise<FileResult<Uint8Array>>;
|
|
19
|
+
close(context: Context): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/** File operations for the directory-backed sync pieces. A missing file or directory fails with `code: "not_found"`. */
|
|
22
|
+
export interface SyncFileSystem {
|
|
23
|
+
joinPath(parts: string[], context: Context): Promise<FileResult<string>>;
|
|
24
|
+
readTextFile(path: string, context: Context): Promise<FileResult<string>>;
|
|
25
|
+
readBinaryFile(path: string, context: Context): Promise<FileResult<Uint8Array>>;
|
|
26
|
+
/** Open a file for bounded reads, so a body streams back without being read whole. */
|
|
27
|
+
openBinaryReader(path: string, options: {
|
|
28
|
+
noFollow?: boolean;
|
|
29
|
+
} | undefined, context: Context): Promise<FileResult<SyncFileReader>>;
|
|
30
|
+
writeFile(path: string, content: string | Uint8Array, context: Context): Promise<FileResult<void>>;
|
|
31
|
+
/** Append to a file, creating it: a body is written chunk by chunk as it streams. */
|
|
32
|
+
appendFile(path: string, content: string | Uint8Array, context: Context): Promise<FileResult<void>>;
|
|
33
|
+
renameFile(sourcePath: string, destinationPath: string, context: Context): Promise<FileResult<void>>;
|
|
34
|
+
listDir(path: string, context: Context): Promise<FileResult<SyncFileInfo[]>>;
|
|
35
|
+
createDir(path: string, options: {
|
|
36
|
+
recursive?: boolean;
|
|
37
|
+
} | undefined, context: Context): Promise<FileResult<void>>;
|
|
38
|
+
remove(path: string, options: {
|
|
39
|
+
recursive?: boolean;
|
|
40
|
+
force?: boolean;
|
|
41
|
+
} | undefined, context: Context): Promise<FileResult<void>>;
|
|
42
|
+
}
|
|
43
|
+
/** Whether `result` failed because the file or directory is missing. */
|
|
44
|
+
export declare function isNotFound(result: FileResult<unknown>): boolean;
|
|
45
|
+
export declare function unwrap<T>(result: FileResult<T>): T;
|
|
46
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/sync/files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,sEAAsE;AACtE,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAErH,yBAAyB;AACzB,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAA;CAAE,CAAC;AAEtG,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACxF,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,wHAAwH;AACxH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IACzE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAChF,sFAAsF;IACtF,gBAAgB,CACf,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,EAC3C,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACnG,qFAAqF;IACrF,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACpG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACrG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC7E,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACnH,MAAM,CACL,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,EAC7D,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;CAC7B;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,OAAO,CAE/D;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAGlD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The file operations the directory-backed sync pieces need, as an interface: any environment that has them (Node,
|
|
2
|
+
// a container, a remote host) can back a sync remote or the host's sync state. Shaped as Pi Durable's `FileSystem`
|
|
3
|
+
// (`@earendil-works/pi-durable/env`), so its environments pass as they are.
|
|
4
|
+
/** Whether `result` failed because the file or directory is missing. */
|
|
5
|
+
export function isNotFound(result) {
|
|
6
|
+
return !result.ok && result.error.code === "not_found";
|
|
7
|
+
}
|
|
8
|
+
export function unwrap(result) {
|
|
9
|
+
if (!result.ok)
|
|
10
|
+
throw result.error;
|
|
11
|
+
return result.value;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/sync/files.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,mHAAmH;AACnH,4EAA4E;AAyC5E,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,MAA2B;IACrD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAK,MAAM,CAAC,KAAqC,CAAC,IAAI,KAAK,WAAW,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,MAAM,CAAI,MAAqB;IAC9C,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,MAAM,CAAC,KAAK,CAAC;IACnC,OAAO,MAAM,CAAC,KAAK,CAAC;AACrB,CAAC","sourcesContent":["// The file operations the directory-backed sync pieces need, as an interface: any environment that has them (Node,\n// a container, a remote host) can back a sync remote or the host's sync state. Shaped as Pi Durable's `FileSystem`\n// (`@earendil-works/pi-durable/env`), so its environments pass as they are.\n\nimport type { Context } from \"../context/index.ts\";\n\n/** An operation's outcome: its value, or the error it failed with. */\nexport type FileResult<T> = { readonly ok: true; readonly value: T } | { readonly ok: false; readonly error: Error };\n\n/** A directory entry. */\nexport type SyncFileInfo = { readonly name: string; readonly kind: \"file\" | \"directory\" | \"symlink\" };\n\n/** A file opened for reads at offsets: what streaming a body back needs. */\nexport interface SyncFileReader {\n\t/** Up to `length` bytes at `offset`; fewer only at end of file. */\n\tread(offset: number, length: number, context: Context): Promise<FileResult<Uint8Array>>;\n\tclose(context: Context): Promise<void>;\n}\n\n/** File operations for the directory-backed sync pieces. A missing file or directory fails with `code: \"not_found\"`. */\nexport interface SyncFileSystem {\n\tjoinPath(parts: string[], context: Context): Promise<FileResult<string>>;\n\treadTextFile(path: string, context: Context): Promise<FileResult<string>>;\n\treadBinaryFile(path: string, context: Context): Promise<FileResult<Uint8Array>>;\n\t/** Open a file for bounded reads, so a body streams back without being read whole. */\n\topenBinaryReader(\n\t\tpath: string,\n\t\toptions: { noFollow?: boolean } | undefined,\n\t\tcontext: Context,\n\t): Promise<FileResult<SyncFileReader>>;\n\twriteFile(path: string, content: string | Uint8Array, context: Context): Promise<FileResult<void>>;\n\t/** Append to a file, creating it: a body is written chunk by chunk as it streams. */\n\tappendFile(path: string, content: string | Uint8Array, context: Context): Promise<FileResult<void>>;\n\trenameFile(sourcePath: string, destinationPath: string, context: Context): Promise<FileResult<void>>;\n\tlistDir(path: string, context: Context): Promise<FileResult<SyncFileInfo[]>>;\n\tcreateDir(path: string, options: { recursive?: boolean } | undefined, context: Context): Promise<FileResult<void>>;\n\tremove(\n\t\tpath: string,\n\t\toptions: { recursive?: boolean; force?: boolean } | undefined,\n\t\tcontext: Context,\n\t): Promise<FileResult<void>>;\n}\n\n/** Whether `result` failed because the file or directory is missing. */\nexport function isNotFound(result: FileResult<unknown>): boolean {\n\treturn !result.ok && (result.error as { readonly code?: unknown }).code === \"not_found\";\n}\n\nexport function unwrap<T>(result: FileResult<T>): T {\n\tif (!result.ok) throw result.error;\n\treturn result.value;\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Context } from "../context/index.ts";
|
|
2
|
+
import type { SyncBody } from "./batch.ts";
|
|
3
|
+
import { type SyncFileSystem } from "./files.ts";
|
|
4
|
+
import { type JsonObject, type PutBatchResult, type RemoteListing, type Seq, type SessionChanges, type SessionSyncMaintenance } from "./remote.ts";
|
|
5
|
+
/** A session ID names a file or directory: refuse anything that could leave the root. */
|
|
6
|
+
export declare function checkSessionId(sessionId: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* A remote store in a directory, laid out as the real remote is: per session, one slot per batch start, holding where
|
|
9
|
+
* the batch ends and which device created it, and snapshots named by their end. As the real remote, it creates a slot
|
|
10
|
+
* only where the history ends. Creating a slot is check-then-write,
|
|
11
|
+
* without the atomicity of the real remote across processes: for development and tests, with one process writing.
|
|
12
|
+
*
|
|
13
|
+
* ```text
|
|
14
|
+
* {root}/{session}/slots/{after}.json { after, to, device, archive?, folded? }, written once
|
|
15
|
+
* {root}/{session}/batches/{after}.batch the commits (or an archive), until folded
|
|
16
|
+
* {root}/{session}/snapshots/{to}.batch a store archive
|
|
17
|
+
* {root}/{session}/meta.json the host's description, last write wins
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class FileSystemSyncRemote implements SessionSyncMaintenance {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(fs: SyncFileSystem, root: string);
|
|
23
|
+
putBatch(sessionId: string, after: Seq, to: Seq, device: string, body: SyncBody, context: Context, options?: {
|
|
24
|
+
readonly archive?: boolean;
|
|
25
|
+
}): Promise<PutBatchResult>;
|
|
26
|
+
getBatch(sessionId: string, after: Seq, context: Context): Promise<SyncBody | undefined>;
|
|
27
|
+
getSnapshot(sessionId: string, to: Seq, context: Context): Promise<SyncBody | undefined>;
|
|
28
|
+
putSnapshot(sessionId: string, to: Seq, body: SyncBody, context: Context): Promise<void>;
|
|
29
|
+
foldBatches(sessionId: string, afters: readonly Seq[], context: Context): Promise<void>;
|
|
30
|
+
deleteSnapshots(sessionId: string, snapshots: readonly Seq[], context: Context): Promise<void>;
|
|
31
|
+
list(sessionId: string, context: Context): Promise<RemoteListing>;
|
|
32
|
+
/** Every session, every time: a directory keeps no change order. */
|
|
33
|
+
sessions(_cursor: string | undefined, context: Context): Promise<SessionChanges>;
|
|
34
|
+
putMeta(sessionId: string, meta: JsonObject, context: Context): Promise<void>;
|
|
35
|
+
getMeta(sessionId: string, context: Context): Promise<JsonObject | undefined>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=filesystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/sync/filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAc,KAAK,cAAc,EAAU,MAAM,YAAY,CAAC;AACrE,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,aAAa,EAElB,KAAK,GAAG,EACR,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,MAAM,aAAa,CAAC;AAcrB,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,YAAW,sBAAsB;;IAIlE,YAAY,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAG3C;IAEK,QAAQ,CACb,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,GAAG,EACV,EAAE,EAAE,GAAG,EACP,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,OAAO,CAAC,cAAc,CAAC,CAgBzB;IAEK,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAI7F;IAED,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAEvF;IAEK,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7F;IAEK,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5F;IAEK,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnG;IAEK,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CActE;IAED,oEAAoE;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBrF;IAEK,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;IAEK,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAGlF;CAuED"}
|