@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,267 @@
|
|
|
1
|
+
// The router (slice 10 §2, D1, D2, D8): the registry `Http` that plugins contribute routes, wraps, sockets, allowed
|
|
2
|
+
// hosts, framers, relays and CSP sources to, and its `compose`, which builds the router every request reads: patterns
|
|
3
|
+
// matched segment by segment (exact before `:name` before a trailing `*`), each route's wraps resolved in phase and
|
|
4
|
+
// contributor order, conflicts reported with the first by plugin name winning.
|
|
5
|
+
import { defineRegistry } from "../../registries/index.js";
|
|
6
|
+
/** The registry the HTTP component defines and serves (`http.facet`, plugin `chord.http`). */
|
|
7
|
+
export const Http = defineRegistry("chord.http", { version: 1 });
|
|
8
|
+
/** A plugin socket's largest frame unless its contribution says otherwise: 1 MiB. */
|
|
9
|
+
const DEFAULT_MAX_PAYLOAD = 1024 * 1024;
|
|
10
|
+
/**
|
|
11
|
+
* The methods a Web `Request` cannot carry (the Fetch standard's forbidden methods): answered 501 at the wire, a route
|
|
12
|
+
* for one refused at compose.
|
|
13
|
+
*/
|
|
14
|
+
export const UNCARRIED = new Set(["CONNECT", "TRACE", "TRACK"]);
|
|
15
|
+
/** Builds the router from `table` (the registry's `compose`): pure, conflicts reported, the first by plugin name wins. */
|
|
16
|
+
export function composeRouter(table, { report }) {
|
|
17
|
+
const routes = new Map();
|
|
18
|
+
const sockets = emptyNode();
|
|
19
|
+
const entries = [];
|
|
20
|
+
const hosts = new Set();
|
|
21
|
+
const framers = new Set();
|
|
22
|
+
const relays = [];
|
|
23
|
+
const csp = new Map();
|
|
24
|
+
const scripts = [];
|
|
25
|
+
const socketHandlers = new Set();
|
|
26
|
+
for (const { plugin, value } of table) {
|
|
27
|
+
for (const host of value.hosts ?? [])
|
|
28
|
+
hosts.add(host.toLowerCase());
|
|
29
|
+
for (const framer of value.framers ?? [])
|
|
30
|
+
framers.add(framer);
|
|
31
|
+
relays.push(...(value.relays ?? []));
|
|
32
|
+
scripts.push(...(value.scripts ?? []));
|
|
33
|
+
for (const [directive, sources] of Object.entries(value.csp ?? {})) {
|
|
34
|
+
csp.set(directive, [...(csp.get(directive) ?? []), ...sources]);
|
|
35
|
+
}
|
|
36
|
+
for (const [key, route] of Object.entries(value.routes ?? {})) {
|
|
37
|
+
const parsed = parseRoute(key);
|
|
38
|
+
if (parsed === undefined) {
|
|
39
|
+
report({ message: `route "${key}" is no "METHOD /pattern"`, plugins: [plugin] });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (UNCARRIED.has(parsed.method)) {
|
|
43
|
+
report({ message: `route "${key}": ${parsed.method} is served for no resource (501)`, plugins: [plugin] });
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
let tree = routes.get(parsed.method);
|
|
47
|
+
if (tree === undefined) {
|
|
48
|
+
tree = emptyNode();
|
|
49
|
+
routes.set(parsed.method, tree);
|
|
50
|
+
}
|
|
51
|
+
const options = typeof route === "function" ? { handler: route } : route;
|
|
52
|
+
const entry = {
|
|
53
|
+
pattern: key,
|
|
54
|
+
plugin,
|
|
55
|
+
handler: options.handler,
|
|
56
|
+
public: options.public === true || options.crossSite === true,
|
|
57
|
+
page: options.page === true,
|
|
58
|
+
crossSite: options.crossSite === true,
|
|
59
|
+
segments: parsed.segments,
|
|
60
|
+
wraps: [],
|
|
61
|
+
};
|
|
62
|
+
const taken = insert(tree, parsed.segments, entry);
|
|
63
|
+
if (taken === undefined)
|
|
64
|
+
entries.push(entry);
|
|
65
|
+
else
|
|
66
|
+
report({ message: `route "${key}" is contributed twice`, plugins: [taken.plugin, plugin] });
|
|
67
|
+
}
|
|
68
|
+
const maxPayload = value.maxPayload ?? DEFAULT_MAX_PAYLOAD;
|
|
69
|
+
for (const [pattern, socket] of Object.entries(value.sockets ?? {})) {
|
|
70
|
+
const segments = parsePattern(pattern);
|
|
71
|
+
if (segments === undefined) {
|
|
72
|
+
report({ message: `socket "${pattern}" is no pattern`, plugins: [plugin] });
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const { handler, public: open } = typeof socket === "function" ? { handler: socket, public: undefined } : socket;
|
|
76
|
+
const entry = { pattern, plugin, handler, public: open === true, segments, maxPayload };
|
|
77
|
+
const taken = insert(sockets, segments, entry);
|
|
78
|
+
if (taken === undefined)
|
|
79
|
+
socketHandlers.add(handler);
|
|
80
|
+
else
|
|
81
|
+
report({ message: `socket "${pattern}" is contributed twice`, plugins: [taken.plugin, plugin] });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
resolveWraps(table, entries, report);
|
|
85
|
+
const get = routes.get("GET");
|
|
86
|
+
const head = routes.get("HEAD");
|
|
87
|
+
return {
|
|
88
|
+
route: (method, path) => {
|
|
89
|
+
// `HEAD` falls back to `GET` per path: an explicit `HEAD` route elsewhere hides no `GET` route.
|
|
90
|
+
if (method === "HEAD")
|
|
91
|
+
return orElse(head === undefined ? undefined : lookup(head, path), get, path);
|
|
92
|
+
const tree = routes.get(method);
|
|
93
|
+
return tree === undefined ? undefined : lookup(tree, path);
|
|
94
|
+
},
|
|
95
|
+
socket: (path) => lookup(sockets, path),
|
|
96
|
+
hosts,
|
|
97
|
+
framers,
|
|
98
|
+
relays,
|
|
99
|
+
csp,
|
|
100
|
+
scripts,
|
|
101
|
+
socketHandlers,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function emptyNode() {
|
|
105
|
+
return { exact: new Map(), param: undefined, rest: undefined, entry: undefined };
|
|
106
|
+
}
|
|
107
|
+
/** `"GET /notes/:id"` as its method and segments; `undefined` when it is none. */
|
|
108
|
+
function parseRoute(key) {
|
|
109
|
+
const space = key.indexOf(" ");
|
|
110
|
+
if (space <= 0)
|
|
111
|
+
return undefined;
|
|
112
|
+
const method = key.slice(0, space);
|
|
113
|
+
if (!/^[A-Z]+$/.test(method))
|
|
114
|
+
return undefined;
|
|
115
|
+
const segments = parsePattern(key.slice(space + 1));
|
|
116
|
+
return segments === undefined ? undefined : { method, segments };
|
|
117
|
+
}
|
|
118
|
+
/** A pattern's segments (`/files/*`, `/notes/:id`); `undefined` for one that is not a path or has `*` before its end. */
|
|
119
|
+
function parsePattern(pattern) {
|
|
120
|
+
if (!pattern.startsWith("/"))
|
|
121
|
+
return undefined;
|
|
122
|
+
const parts = pattern.slice(1).split("/");
|
|
123
|
+
const segments = [];
|
|
124
|
+
for (const [index, part] of parts.entries()) {
|
|
125
|
+
if (part === "*") {
|
|
126
|
+
if (index !== parts.length - 1)
|
|
127
|
+
return undefined;
|
|
128
|
+
segments.push({ kind: "rest" });
|
|
129
|
+
}
|
|
130
|
+
else if (part.startsWith(":")) {
|
|
131
|
+
if (part.length === 1)
|
|
132
|
+
return undefined;
|
|
133
|
+
segments.push({ kind: "param", name: part.slice(1) });
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
segments.push({ kind: "exact", text: part });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return segments;
|
|
140
|
+
}
|
|
141
|
+
/** Puts `entry` at `segments` in `tree`; returns the entry already there (the first by plugin name keeps it). */
|
|
142
|
+
function insert(tree, segments, entry) {
|
|
143
|
+
let node = tree;
|
|
144
|
+
for (const segment of segments) {
|
|
145
|
+
if (segment.kind === "rest") {
|
|
146
|
+
if (node.rest !== undefined)
|
|
147
|
+
return node.rest;
|
|
148
|
+
node.rest = entry;
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
if (segment.kind === "exact") {
|
|
152
|
+
let next = node.exact.get(segment.text);
|
|
153
|
+
if (next === undefined) {
|
|
154
|
+
next = emptyNode();
|
|
155
|
+
node.exact.set(segment.text, next);
|
|
156
|
+
}
|
|
157
|
+
node = next;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
// `:a` and `:b` at one position share the node: one shape, so the same pattern twice is a conflict.
|
|
161
|
+
node.param ??= emptyNode();
|
|
162
|
+
node = node.param;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (node.entry !== undefined)
|
|
166
|
+
return node.entry;
|
|
167
|
+
node.entry = entry;
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
/** `found`, or when it is no route the `GET` route for `path` (`HEAD`'s fallback). */
|
|
171
|
+
function orElse(found, get, path) {
|
|
172
|
+
if (found !== undefined || get === undefined)
|
|
173
|
+
return found;
|
|
174
|
+
return lookup(get, path);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The entry `path` matches in `tree` with its params named by the entry's own pattern, the most specific segment by
|
|
178
|
+
* segment from the left (exact before `:name` before `*`); `bad_path` for a segment that does not decode, or a `:name`
|
|
179
|
+
* or rest segment decoding to one containing `/`, `\` or NUL, or to `.` or `..` (a param must never be a path).
|
|
180
|
+
*/
|
|
181
|
+
function lookup(tree, path) {
|
|
182
|
+
const raw = path.slice(1).split("/");
|
|
183
|
+
const decoded = [];
|
|
184
|
+
for (const part of raw) {
|
|
185
|
+
if (!part.includes("%")) {
|
|
186
|
+
decoded.push(part);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
decoded.push(decodeURIComponent(part));
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return "bad_path";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const found = walk(tree, decoded, 0, []);
|
|
197
|
+
if (found === undefined)
|
|
198
|
+
return undefined;
|
|
199
|
+
const params = {};
|
|
200
|
+
let capture = 0;
|
|
201
|
+
for (const segment of found.entry.segments) {
|
|
202
|
+
if (segment.kind !== "param")
|
|
203
|
+
continue;
|
|
204
|
+
const value = found.captures[capture++];
|
|
205
|
+
if (!safe(value))
|
|
206
|
+
return "bad_path";
|
|
207
|
+
params[segment.name] = value;
|
|
208
|
+
}
|
|
209
|
+
if (found.rest !== undefined) {
|
|
210
|
+
const rest = decoded.slice(found.rest);
|
|
211
|
+
if (!rest.every(safe))
|
|
212
|
+
return "bad_path";
|
|
213
|
+
params["*"] = rest.join("/");
|
|
214
|
+
}
|
|
215
|
+
const { segments: _segments, ...entry } = found.entry;
|
|
216
|
+
return { ...entry, params };
|
|
217
|
+
}
|
|
218
|
+
/** Whether a decoded segment may be a param: no `/`, `\` or NUL, not `.` or `..`. */
|
|
219
|
+
function safe(segment) {
|
|
220
|
+
return segment !== "." && segment !== ".." && !/[/\\\0]/.test(segment);
|
|
221
|
+
}
|
|
222
|
+
/** Depth first in precedence order: the first match found is the most specific from the left. */
|
|
223
|
+
function walk(node, parts, index, captures) {
|
|
224
|
+
if (index === parts.length) {
|
|
225
|
+
if (node.entry !== undefined)
|
|
226
|
+
return { entry: node.entry, captures, rest: undefined };
|
|
227
|
+
// `/files/*` matches `/files`: the rest is empty.
|
|
228
|
+
return node.rest === undefined ? undefined : { entry: node.rest, captures, rest: index };
|
|
229
|
+
}
|
|
230
|
+
const part = parts[index];
|
|
231
|
+
const exact = node.exact.get(part);
|
|
232
|
+
const viaExact = exact === undefined ? undefined : walk(exact, parts, index + 1, captures);
|
|
233
|
+
if (viaExact !== undefined)
|
|
234
|
+
return viaExact;
|
|
235
|
+
if (node.param !== undefined && part !== "") {
|
|
236
|
+
const viaParam = walk(node.param, parts, index + 1, [...captures, part]);
|
|
237
|
+
if (viaParam !== undefined)
|
|
238
|
+
return viaParam;
|
|
239
|
+
}
|
|
240
|
+
return node.rest === undefined ? undefined : { entry: node.rest, captures, rest: index };
|
|
241
|
+
}
|
|
242
|
+
/** The wrap phases, outermost first. */
|
|
243
|
+
const PHASES = ["observe", "headers", "transform"];
|
|
244
|
+
/**
|
|
245
|
+
* Gives every route its wraps: by phase (outermost first), within a phase in contributor (table) order; `own` ones
|
|
246
|
+
* around their plugin's routes, `all` ones around every route; one naming a route nobody contributes is reported.
|
|
247
|
+
*/
|
|
248
|
+
function resolveWraps(table, routes, report) {
|
|
249
|
+
const all = [];
|
|
250
|
+
for (const { plugin, value } of table)
|
|
251
|
+
for (const wrap of value.wraps ?? [])
|
|
252
|
+
all.push({ wrap, plugin });
|
|
253
|
+
all.sort((a, b) => PHASES.indexOf(a.wrap.phase) - PHASES.indexOf(b.wrap.phase));
|
|
254
|
+
for (const { wrap, plugin } of all) {
|
|
255
|
+
if (wrap.route !== undefined && !routes.some((route) => route.pattern === wrap.route)) {
|
|
256
|
+
report({
|
|
257
|
+
message: `wrap "${wrap.name}" names route "${wrap.route}", which nobody contributes`,
|
|
258
|
+
plugins: [plugin],
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
for (const route of routes) {
|
|
263
|
+
route.wraps = all.filter(({ wrap, plugin }) => (wrap.scope === "all" || plugin === route.plugin) &&
|
|
264
|
+
(wrap.route === undefined || wrap.route === route.pattern));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/node/http/router.ts"],"names":[],"mappings":"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","sourcesContent":["// The router (slice 10 §2, D1, D2, D8): the registry `Http` that plugins contribute routes, wraps, sockets, allowed\n// hosts, framers, relays and CSP sources to, and its `compose`, which builds the router every request reads: patterns\n// matched segment by segment (exact before `:name` before a trailing `*`), each route's wraps resolved in phase and\n// contributor order, conflicts reported with the first by plugin name winning.\n\nimport type { WebSocket } from \"ws\";\nimport type { Ctx } from \"../../host/index.ts\";\nimport { type ComposeContext, defineRegistry, type RegistryTable } from \"../../registries/index.ts\";\nimport type { HttpRequest } from \"./request.ts\";\nimport type { HttpResponse } from \"./response.ts\";\n\n/** A route: answers a request with a response description, in the request's scope (`ctx.principal`, its signal). */\nexport type HttpRoute = (request: HttpRequest, ctx: Ctx) => Promise<HttpResponse>;\n\n/**\n * A route with its options: `public` serves it without a principal (deny by default: a route without one answers 401\n * to a request no authenticator recognized); `page` admits a top-level navigation from another site (a link to it)\n * with its authentication; `crossSite` admits any foreign request (a webhook), always anonymous, so public too.\n */\nexport type HttpRouteOptions = {\n\treadonly handler: HttpRoute;\n\treadonly public?: true;\n\treadonly page?: true;\n\treadonly crossSite?: true;\n};\n\n/** A wrap's phases, outermost first. */\nexport type WrapPhase = \"observe\" | \"headers\" | \"transform\";\n\n/** A wrap (D2): runs around routes in its phase, around its own plugin's routes unless `scope` is `\"all\"`. */\nexport type HttpWrap = {\n\treadonly name: string;\n\treadonly phase: WrapPhase;\n\t/** `\"own\"` (default): around the contributing plugin's routes; `\"all\"`: every route. */\n\treadonly scope?: \"own\" | \"all\";\n\t/** Only around this route (`\"GET /notes/:id\"`); a route nobody contributes is a reported conflict. */\n\treadonly route?: string;\n\treadonly wrap: (\n\t\trequest: HttpRequest,\n\t\tnext: (request: HttpRequest) => Promise<HttpResponse>,\n\t\tctx: Ctx,\n\t) => Promise<HttpResponse>;\n};\n\n/**\n * A plugin socket's handler (D6): a `ws` WebSocket after the checks and authentication, its `error` listener attached;\n * its scope lasts until the socket closes.\n */\nexport type HttpSocket = (socket: WebSocketHandle, request: HttpRequest, ctx: Ctx) => void | Promise<void>;\n\n/** A plugin socket with its options: `public` accepts it without a principal (else 401 before the handler runs). */\nexport type HttpSocketOptions = { readonly handler: HttpSocket; readonly public?: true };\n\n/** A plugin socket: `ws`'s WebSocket, for the plugin's own protocol. */\nexport type WebSocketHandle = WebSocket;\n\n/**\n * A relay (p2's Radius): a forwarder on loopback that sends forwarded headers. `verify` recognizes its requests (a\n * secret header, a signature) and names the origin the request came from and the origin allowed to frame it.\n */\nexport type HttpRelay = {\n\treadonly name: string;\n\treadonly verify: (request: Request) => { readonly origin: string; readonly framer?: string } | undefined;\n};\n\n/** What a plugin contributes to `Http`: a plain value, or a writable of one (its change recomposes the router). */\nexport type HttpContribution = {\n\t/** Routes by `\"METHOD /pattern\"`: exact segments, `:name`, a trailing `/*`. */\n\treadonly routes?: Readonly<Record<string, HttpRoute | HttpRouteOptions>>;\n\treadonly wraps?: readonly HttpWrap[];\n\t/** Plugin sockets by pattern (no method). */\n\treadonly sockets?: Readonly<Record<string, HttpSocket | HttpSocketOptions>>;\n\t/** The largest frame this contribution's sockets accept; 1 MiB by default. */\n\treadonly maxPayload?: number;\n\t/** Hosts allowed besides loopback, as the client names them (`notes.example.com`): requests through them are https. */\n\treadonly hosts?: readonly string[];\n\t/** Origins allowed to frame the app's pages (CSP `frame-ancestors`). */\n\treadonly framers?: readonly string[];\n\t/** Relays whose forwarded requests are admitted (verified) on loopback. */\n\treadonly relays?: readonly HttpRelay[];\n\t/** Extra CSP sources by directive (`{ \"img-src\": [\"https://cdn.example.com\"] }`). */\n\treadonly csp?: Readonly<Record<string, readonly string[]>>;\n\t/**\n\t * The paths scripts load from (`/_chord/web/`): with any, `script-src` is these paths of the request's origin and the\n\t * response's nonce instead of the whole origin, so no other same-origin response (an upload served as JavaScript)\n\t * runs as a script.\n\t */\n\treadonly scripts?: readonly string[];\n};\n\n/** The router a request uses: as it was when the request started. */\nexport type Router = {\n\t/** The route for `method` and `path`, with its params and wraps; `bad_path` for a malformed one. */\n\troute(method: string, path: string): RouteMatch | \"bad_path\" | undefined;\n\t/** The plugin socket for `path`. */\n\tsocket(path: string): SocketMatch | \"bad_path\" | undefined;\n\t/** The hosts contributions allow (lowercased). */\n\treadonly hosts: ReadonlySet<string>;\n\t/** The origins allowed to frame pages. */\n\treadonly framers: ReadonlySet<string>;\n\t/** The relays, in contributor order. */\n\treadonly relays: readonly HttpRelay[];\n\t/** Extra CSP sources by directive. */\n\treadonly csp: ReadonlyMap<string, readonly string[]>;\n\t/** The paths scripts load from; none: the whole origin. */\n\treadonly scripts: readonly string[];\n\t/** The socket handlers it serves: a socket handed out by one no longer here is closed. */\n\treadonly socketHandlers: ReadonlySet<HttpSocket>;\n};\n\n/** A matched route: its pattern, plugin, params, handler, options and wraps (outermost first). */\nexport type RouteMatch = {\n\treadonly pattern: string;\n\treadonly plugin: string;\n\treadonly params: Readonly<Record<string, string>>;\n\treadonly handler: HttpRoute;\n\t/** Served without a principal: marked `public`, or `crossSite` (always anonymous). */\n\treadonly public: boolean;\n\treadonly page: boolean;\n\treadonly crossSite: boolean;\n\treadonly wraps: readonly ResolvedWrap[];\n};\n\n/** A matched plugin socket. */\nexport type SocketMatch = {\n\treadonly pattern: string;\n\treadonly plugin: string;\n\treadonly params: Readonly<Record<string, string>>;\n\treadonly handler: HttpSocket;\n\treadonly public: boolean;\n\treadonly maxPayload: number;\n};\n\n/** A wrap as a route runs it, with its plugin. */\nexport type ResolvedWrap = { readonly wrap: HttpWrap; readonly plugin: string };\n\n/** The registry the HTTP component defines and serves (`http.facet`, plugin `chord.http`). */\nexport const Http = defineRegistry<HttpContribution, Router>(\"chord.http\", { version: 1 });\n\n/** A plugin socket's largest frame unless its contribution says otherwise: 1 MiB. */\nconst DEFAULT_MAX_PAYLOAD = 1024 * 1024;\n\n/**\n * The methods a Web `Request` cannot carry (the Fetch standard's forbidden methods): answered 501 at the wire, a route\n * for one refused at compose.\n */\nexport const UNCARRIED: ReadonlySet<string> = new Set([\"CONNECT\", \"TRACE\", \"TRACK\"]);\n\n/** Builds the router from `table` (the registry's `compose`): pure, conflicts reported, the first by plugin name wins. */\nexport function composeRouter(table: RegistryTable<HttpContribution>, { report }: ComposeContext): Router {\n\tconst routes = new Map<string, Node<RouteEntry>>();\n\tconst sockets: Node<SocketEntry> = emptyNode();\n\tconst entries: RouteEntry[] = [];\n\tconst hosts = new Set<string>();\n\tconst framers = new Set<string>();\n\tconst relays: HttpRelay[] = [];\n\tconst csp = new Map<string, string[]>();\n\tconst scripts: string[] = [];\n\tconst socketHandlers = new Set<HttpSocket>();\n\tfor (const { plugin, value } of table) {\n\t\tfor (const host of value.hosts ?? []) hosts.add(host.toLowerCase());\n\t\tfor (const framer of value.framers ?? []) framers.add(framer);\n\t\trelays.push(...(value.relays ?? []));\n\t\tscripts.push(...(value.scripts ?? []));\n\t\tfor (const [directive, sources] of Object.entries(value.csp ?? {})) {\n\t\t\tcsp.set(directive, [...(csp.get(directive) ?? []), ...sources]);\n\t\t}\n\t\tfor (const [key, route] of Object.entries(value.routes ?? {})) {\n\t\t\tconst parsed = parseRoute(key);\n\t\t\tif (parsed === undefined) {\n\t\t\t\treport({ message: `route \"${key}\" is no \"METHOD /pattern\"`, plugins: [plugin] });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (UNCARRIED.has(parsed.method)) {\n\t\t\t\treport({ message: `route \"${key}\": ${parsed.method} is served for no resource (501)`, plugins: [plugin] });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet tree = routes.get(parsed.method);\n\t\t\tif (tree === undefined) {\n\t\t\t\ttree = emptyNode();\n\t\t\t\troutes.set(parsed.method, tree);\n\t\t\t}\n\t\t\tconst options = typeof route === \"function\" ? { handler: route } : route;\n\t\t\tconst entry: RouteEntry = {\n\t\t\t\tpattern: key,\n\t\t\t\tplugin,\n\t\t\t\thandler: options.handler,\n\t\t\t\tpublic: options.public === true || options.crossSite === true,\n\t\t\t\tpage: options.page === true,\n\t\t\t\tcrossSite: options.crossSite === true,\n\t\t\t\tsegments: parsed.segments,\n\t\t\t\twraps: [],\n\t\t\t};\n\t\t\tconst taken = insert(tree, parsed.segments, entry);\n\t\t\tif (taken === undefined) entries.push(entry);\n\t\t\telse report({ message: `route \"${key}\" is contributed twice`, plugins: [taken.plugin, plugin] });\n\t\t}\n\t\tconst maxPayload = value.maxPayload ?? DEFAULT_MAX_PAYLOAD;\n\t\tfor (const [pattern, socket] of Object.entries(value.sockets ?? {})) {\n\t\t\tconst segments = parsePattern(pattern);\n\t\t\tif (segments === undefined) {\n\t\t\t\treport({ message: `socket \"${pattern}\" is no pattern`, plugins: [plugin] });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst { handler, public: open } =\n\t\t\t\ttypeof socket === \"function\" ? { handler: socket, public: undefined } : socket;\n\t\t\tconst entry = { pattern, plugin, handler, public: open === true, segments, maxPayload };\n\t\t\tconst taken = insert(sockets, segments, entry);\n\t\t\tif (taken === undefined) socketHandlers.add(handler);\n\t\t\telse report({ message: `socket \"${pattern}\" is contributed twice`, plugins: [taken.plugin, plugin] });\n\t\t}\n\t}\n\tresolveWraps(table, entries, report);\n\tconst get = routes.get(\"GET\");\n\tconst head = routes.get(\"HEAD\");\n\treturn {\n\t\troute: (method, path) => {\n\t\t\t// `HEAD` falls back to `GET` per path: an explicit `HEAD` route elsewhere hides no `GET` route.\n\t\t\tif (method === \"HEAD\") return orElse(head === undefined ? undefined : lookup(head, path), get, path);\n\t\t\tconst tree = routes.get(method);\n\t\t\treturn tree === undefined ? undefined : lookup(tree, path);\n\t\t},\n\t\tsocket: (path) => lookup(sockets, path),\n\t\thosts,\n\t\tframers,\n\t\trelays,\n\t\tcsp,\n\t\tscripts,\n\t\tsocketHandlers,\n\t};\n}\n\n/** One pattern segment: an exact one, `:name`, or the trailing rest (`*`). */\ntype Segment =\n\t| { readonly kind: \"exact\"; readonly text: string }\n\t| { readonly kind: \"param\"; readonly name: string }\n\t| { readonly kind: \"rest\" };\n\n/** What a route contributes, with its wraps once resolved. */\ntype RouteEntry = {\n\treadonly pattern: string;\n\treadonly plugin: string;\n\treadonly handler: HttpRoute;\n\treadonly public: boolean;\n\treadonly page: boolean;\n\treadonly crossSite: boolean;\n\treadonly segments: readonly Segment[];\n\twraps: readonly ResolvedWrap[];\n};\n\n/** What a plugin socket contributes. */\ntype SocketEntry = {\n\treadonly pattern: string;\n\treadonly plugin: string;\n\treadonly handler: HttpSocket;\n\treadonly public: boolean;\n\treadonly segments: readonly Segment[];\n\treadonly maxPayload: number;\n};\n\n/** A node of a pattern tree: its children by kind, and the entry ending here. */\ntype Node<E> = {\n\treadonly exact: Map<string, Node<E>>;\n\t/** Any `:name` at this position (the names are each entry's own). */\n\tparam: Node<E> | undefined;\n\trest: E | undefined;\n\tentry: E | undefined;\n};\n\nfunction emptyNode<E>(): Node<E> {\n\treturn { exact: new Map(), param: undefined, rest: undefined, entry: undefined };\n}\n\n/** `\"GET /notes/:id\"` as its method and segments; `undefined` when it is none. */\nfunction parseRoute(key: string): { readonly method: string; readonly segments: readonly Segment[] } | undefined {\n\tconst space = key.indexOf(\" \");\n\tif (space <= 0) return undefined;\n\tconst method = key.slice(0, space);\n\tif (!/^[A-Z]+$/.test(method)) return undefined;\n\tconst segments = parsePattern(key.slice(space + 1));\n\treturn segments === undefined ? undefined : { method, segments };\n}\n\n/** A pattern's segments (`/files/*`, `/notes/:id`); `undefined` for one that is not a path or has `*` before its end. */\nfunction parsePattern(pattern: string): readonly Segment[] | undefined {\n\tif (!pattern.startsWith(\"/\")) return undefined;\n\tconst parts = pattern.slice(1).split(\"/\");\n\tconst segments: Segment[] = [];\n\tfor (const [index, part] of parts.entries()) {\n\t\tif (part === \"*\") {\n\t\t\tif (index !== parts.length - 1) return undefined;\n\t\t\tsegments.push({ kind: \"rest\" });\n\t\t} else if (part.startsWith(\":\")) {\n\t\t\tif (part.length === 1) return undefined;\n\t\t\tsegments.push({ kind: \"param\", name: part.slice(1) });\n\t\t} else {\n\t\t\tsegments.push({ kind: \"exact\", text: part });\n\t\t}\n\t}\n\treturn segments;\n}\n\n/** Puts `entry` at `segments` in `tree`; returns the entry already there (the first by plugin name keeps it). */\nfunction insert<E>(tree: Node<E>, segments: readonly Segment[], entry: E): E | undefined {\n\tlet node = tree;\n\tfor (const segment of segments) {\n\t\tif (segment.kind === \"rest\") {\n\t\t\tif (node.rest !== undefined) return node.rest;\n\t\t\tnode.rest = entry;\n\t\t\treturn undefined;\n\t\t}\n\t\tif (segment.kind === \"exact\") {\n\t\t\tlet next = node.exact.get(segment.text);\n\t\t\tif (next === undefined) {\n\t\t\t\tnext = emptyNode();\n\t\t\t\tnode.exact.set(segment.text, next);\n\t\t\t}\n\t\t\tnode = next;\n\t\t} else {\n\t\t\t// `:a` and `:b` at one position share the node: one shape, so the same pattern twice is a conflict.\n\t\t\tnode.param ??= emptyNode();\n\t\t\tnode = node.param;\n\t\t}\n\t}\n\tif (node.entry !== undefined) return node.entry;\n\tnode.entry = entry;\n\treturn undefined;\n}\n\n/** `found`, or when it is no route the `GET` route for `path` (`HEAD`'s fallback). */\nfunction orElse(\n\tfound: RouteMatch | \"bad_path\" | undefined,\n\tget: Node<RouteEntry> | undefined,\n\tpath: string,\n): RouteMatch | \"bad_path\" | undefined {\n\tif (found !== undefined || get === undefined) return found;\n\treturn lookup(get, path);\n}\n\n/**\n * The entry `path` matches in `tree` with its params named by the entry's own pattern, the most specific segment by\n * segment from the left (exact before `:name` before `*`); `bad_path` for a segment that does not decode, or a `:name`\n * or rest segment decoding to one containing `/`, `\\` or NUL, or to `.` or `..` (a param must never be a path).\n */\nfunction lookup<E extends { readonly segments: readonly Segment[] }>(\n\ttree: Node<E>,\n\tpath: string,\n): (Omit<E, \"segments\"> & { readonly params: Readonly<Record<string, string>> }) | \"bad_path\" | undefined {\n\tconst raw = path.slice(1).split(\"/\");\n\tconst decoded: string[] = [];\n\tfor (const part of raw) {\n\t\tif (!part.includes(\"%\")) {\n\t\t\tdecoded.push(part);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tdecoded.push(decodeURIComponent(part));\n\t\t} catch {\n\t\t\treturn \"bad_path\";\n\t\t}\n\t}\n\tconst found = walk(tree, decoded, 0, []);\n\tif (found === undefined) return undefined;\n\tconst params: Record<string, string> = {};\n\tlet capture = 0;\n\tfor (const segment of found.entry.segments) {\n\t\tif (segment.kind !== \"param\") continue;\n\t\tconst value = found.captures[capture++]!;\n\t\tif (!safe(value)) return \"bad_path\";\n\t\tparams[segment.name] = value;\n\t}\n\tif (found.rest !== undefined) {\n\t\tconst rest = decoded.slice(found.rest);\n\t\tif (!rest.every(safe)) return \"bad_path\";\n\t\tparams[\"*\"] = rest.join(\"/\");\n\t}\n\tconst { segments: _segments, ...entry } = found.entry;\n\treturn { ...entry, params };\n}\n\n/** Whether a decoded segment may be a param: no `/`, `\\` or NUL, not `.` or `..`. */\nfunction safe(segment: string): boolean {\n\treturn segment !== \".\" && segment !== \"..\" && !/[/\\\\\\0]/.test(segment);\n}\n\n/** A match found by `walk`: its entry, its `:name` values in order, where the rest starts (for `*`). */\ntype Found<E> = { readonly entry: E; readonly captures: readonly string[]; readonly rest: number | undefined };\n\n/** Depth first in precedence order: the first match found is the most specific from the left. */\nfunction walk<E>(node: Node<E>, parts: readonly string[], index: number, captures: string[]): Found<E> | undefined {\n\tif (index === parts.length) {\n\t\tif (node.entry !== undefined) return { entry: node.entry, captures, rest: undefined };\n\t\t// `/files/*` matches `/files`: the rest is empty.\n\t\treturn node.rest === undefined ? undefined : { entry: node.rest, captures, rest: index };\n\t}\n\tconst part = parts[index]!;\n\tconst exact = node.exact.get(part);\n\tconst viaExact = exact === undefined ? undefined : walk(exact, parts, index + 1, captures);\n\tif (viaExact !== undefined) return viaExact;\n\tif (node.param !== undefined && part !== \"\") {\n\t\tconst viaParam = walk(node.param, parts, index + 1, [...captures, part]);\n\t\tif (viaParam !== undefined) return viaParam;\n\t}\n\treturn node.rest === undefined ? undefined : { entry: node.rest, captures, rest: index };\n}\n\n/** The wrap phases, outermost first. */\nconst PHASES: readonly WrapPhase[] = [\"observe\", \"headers\", \"transform\"];\n\n/**\n * Gives every route its wraps: by phase (outermost first), within a phase in contributor (table) order; `own` ones\n * around their plugin's routes, `all` ones around every route; one naming a route nobody contributes is reported.\n */\nfunction resolveWraps(\n\ttable: RegistryTable<HttpContribution>,\n\troutes: RouteEntry[],\n\treport: ComposeContext[\"report\"],\n): void {\n\tconst all: ResolvedWrap[] = [];\n\tfor (const { plugin, value } of table) for (const wrap of value.wraps ?? []) all.push({ wrap, plugin });\n\tall.sort((a, b) => PHASES.indexOf(a.wrap.phase) - PHASES.indexOf(b.wrap.phase));\n\tfor (const { wrap, plugin } of all) {\n\t\tif (wrap.route !== undefined && !routes.some((route) => route.pattern === wrap.route)) {\n\t\t\treport({\n\t\t\t\tmessage: `wrap \"${wrap.name}\" names route \"${wrap.route}\", which nobody contributes`,\n\t\t\t\tplugins: [plugin],\n\t\t\t});\n\t\t}\n\t}\n\tfor (const route of routes) {\n\t\troute.wraps = all.filter(\n\t\t\t({ wrap, plugin }) =>\n\t\t\t\t(wrap.scope === \"all\" || plugin === route.plugin) &&\n\t\t\t\t(wrap.route === undefined || wrap.route === route.pattern),\n\t\t);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { IncomingMessage } from "node:http";
|
|
2
|
+
import type { Duplex } from "node:stream";
|
|
3
|
+
import { type WebSocket } from "ws";
|
|
4
|
+
import { type Context } from "../../context/index.ts";
|
|
5
|
+
import type { Principal } from "../../data/index.ts";
|
|
6
|
+
import type { Host } from "../../host/index.ts";
|
|
7
|
+
import { type PartLimits, type WebSocketLike } from "../../link/index.ts";
|
|
8
|
+
import type { HttpRequest } from "./request.ts";
|
|
9
|
+
import type { HttpRelay, Router, SocketMatch } from "./router.ts";
|
|
10
|
+
/** What admitted an upgrade: the allowed host or the relay it came through (local: neither), and its principal. */
|
|
11
|
+
export type Admission<P extends Principal> = {
|
|
12
|
+
readonly allowed: string | undefined;
|
|
13
|
+
readonly relay: HttpRelay | undefined;
|
|
14
|
+
readonly principal: P;
|
|
15
|
+
};
|
|
16
|
+
/** What the links endpoint gives one socket: its parts' limits and its largest frame (1 MiB by default). */
|
|
17
|
+
export type LinkOptions = {
|
|
18
|
+
readonly limits?: PartLimits;
|
|
19
|
+
readonly maxPayload?: number;
|
|
20
|
+
};
|
|
21
|
+
/** A plugin socket's handler failed: reported, the socket closed (1011). */
|
|
22
|
+
export type SocketFailure = {
|
|
23
|
+
readonly pattern: string;
|
|
24
|
+
readonly plugin: string;
|
|
25
|
+
readonly error: unknown;
|
|
26
|
+
};
|
|
27
|
+
/** The upgraded connections of one HTTP component. */
|
|
28
|
+
export declare class Upgrades {
|
|
29
|
+
#private;
|
|
30
|
+
/**
|
|
31
|
+
* Upgrades `message` to the links endpoint: `host.accept` over the socket (its output capped) as the admitted
|
|
32
|
+
* principal, with `options`' limits; `context` is the parent of the work on the link. `opened` runs once the link
|
|
33
|
+
* is accepted; what it returns runs when its socket closes.
|
|
34
|
+
*/
|
|
35
|
+
link<P extends Principal>(message: IncomingMessage, stream: Duplex, head: Buffer, admission: Admission<P> & LinkOptions, host: Host<P>, context: Context, opened: () => (() => void) | undefined): void;
|
|
36
|
+
/**
|
|
37
|
+
* Upgrades `message` to the plugin socket `match`: its handler gets the socket and `request` in a `host.root` scope
|
|
38
|
+
* acting as the admitted principal that lasts until the socket closes; a handler that throws is reported and closes
|
|
39
|
+
* it (1011).
|
|
40
|
+
*/
|
|
41
|
+
socket<P extends Principal>(message: IncomingMessage, stream: Duplex, head: Buffer, admission: Omit<Admission<P>, "principal"> & {
|
|
42
|
+
/** Anonymous only for a public socket. */
|
|
43
|
+
readonly principal: P | undefined;
|
|
44
|
+
readonly match: SocketMatch;
|
|
45
|
+
readonly request: HttpRequest;
|
|
46
|
+
}, host: Host<P>, context: Context, failed: (failure: SocketFailure) => void): void;
|
|
47
|
+
/**
|
|
48
|
+
* The router changed: connections through a host or a relay no longer there, and plugin sockets whose handler left,
|
|
49
|
+
* are terminated at once and their scopes sealed (no close handshake a peer could ignore).
|
|
50
|
+
*/
|
|
51
|
+
revoke(router: Router): void;
|
|
52
|
+
/** Closes every connection (1001, "going away"); those still open at `deadline` are terminated. */
|
|
53
|
+
close(deadline: Promise<void>): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `socket` as the link sees it, its output capped (p2's `limitedSocket`): before each send, what is still buffered
|
|
57
|
+
* beyond the largest frame being sent must stay under 4 MiB, or the socket is terminated (the client reconnects from
|
|
58
|
+
* snapshots); Chord's flow control keeps a reading client far below it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function limitedSocket(socket: WebSocket): WebSocketLike;
|
|
61
|
+
//# sourceMappingURL=upgrades.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrades.d.ts","sourceRoot":"","sources":["../../../src/node/http/upgrades.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,IAAI,CAAC;AACrD,OAAO,EAAE,KAAK,OAAO,EAAuC,MAAM,wBAAwB,CAAC;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAO,IAAI,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9E,mHAAmH;AACnH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,SAAS,IAAI;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;CACtB,CAAC;AAEF,4GAA4G;AAC5G,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzF,4EAA4E;AAC5E,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAgB3G,sDAAsD;AACtD,qBAAa,QAAQ;;IAGpB;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,SAAS,EACvB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,WAAW,EACrC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EACb,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,GACpC,IAAI,CAeN;IAED;;;;OAIG;IACH,MAAM,CAAC,CAAC,SAAS,SAAS,EACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG;QAC5C,0CAA0C;QAC1C,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;QAC5B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;KAC9B,EACD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EACb,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GACtC,IAAI,CAwBN;IAED;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ3B;IAED,mGAAmG;IAC7F,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlD;CAYD;AAwDD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,CAkC9D"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// Upgraded connections (slice 10 §2, D6, Q6): the links endpoint (`host.accept` over a WebSocket with a per-socket
|
|
2
|
+
// output cap) and plugin sockets (a `ws` WebSocket handed to the contribution's handler for its own protocol, in a scope
|
|
3
|
+
// lasting until it closes, kept alive by a heartbeat). Each connection is kept with what admitted it: when that leaves
|
|
4
|
+
// (its allowed host, its relay, its socket handler) it is terminated at once and its scope sealed (decision "Slice 10
|
|
5
|
+
// fix round, allowed hosts only through contributions"); the component's close closes all (1001), terminating at its
|
|
6
|
+
// timeout those that never acknowledge.
|
|
7
|
+
import { WebSocketServer } from "ws";
|
|
8
|
+
import { withAbortSignal, withoutAbortSignal } from "../../context/index.js";
|
|
9
|
+
import { webSocketLink } from "../../link/index.js";
|
|
10
|
+
/** A link socket's largest frame unless `links.options` says otherwise: 1 MiB. */
|
|
11
|
+
const DEFAULT_LINK_PAYLOAD = 1024 * 1024;
|
|
12
|
+
/** The upgraded connections of one HTTP component. */
|
|
13
|
+
export class Upgrades {
|
|
14
|
+
#open = new Set();
|
|
15
|
+
/**
|
|
16
|
+
* Upgrades `message` to the links endpoint: `host.accept` over the socket (its output capped) as the admitted
|
|
17
|
+
* principal, with `options`' limits; `context` is the parent of the work on the link. `opened` runs once the link
|
|
18
|
+
* is accepted; what it returns runs when its socket closes.
|
|
19
|
+
*/
|
|
20
|
+
link(message, stream, head, admission, host, context, opened) {
|
|
21
|
+
const { principal, limits } = admission;
|
|
22
|
+
upgrade(message, stream, head, admission.maxPayload ?? DEFAULT_LINK_PAYLOAD, (socket) => {
|
|
23
|
+
const link = webSocketLink(limitedSocket(socket));
|
|
24
|
+
this.#keep({
|
|
25
|
+
socket,
|
|
26
|
+
allowed: admission.allowed,
|
|
27
|
+
relay: admission.relay,
|
|
28
|
+
handler: undefined,
|
|
29
|
+
seal: () => link.close(),
|
|
30
|
+
});
|
|
31
|
+
host.accept(link, { principal, ...(limits === undefined ? {} : { limits }) }, context);
|
|
32
|
+
const closed = opened();
|
|
33
|
+
if (closed !== undefined)
|
|
34
|
+
socket.once("close", closed);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Upgrades `message` to the plugin socket `match`: its handler gets the socket and `request` in a `host.root` scope
|
|
39
|
+
* acting as the admitted principal that lasts until the socket closes; a handler that throws is reported and closes
|
|
40
|
+
* it (1011).
|
|
41
|
+
*/
|
|
42
|
+
socket(message, stream, head, admission, host, context, failed) {
|
|
43
|
+
const { principal, match, request } = admission;
|
|
44
|
+
upgrade(message, stream, head, match.maxPayload, (socket) => {
|
|
45
|
+
const closed = new AbortController();
|
|
46
|
+
const seal = () => closed.abort(new Error("http: the socket closed"));
|
|
47
|
+
socket.once("close", seal);
|
|
48
|
+
this.#keep({ socket, allowed: admission.allowed, relay: admission.relay, handler: match.handler, seal });
|
|
49
|
+
heartbeat(socket);
|
|
50
|
+
const scope = withAbortSignal(closed.signal, withoutAbortSignal(context));
|
|
51
|
+
const run = async (ctx) => {
|
|
52
|
+
try {
|
|
53
|
+
await match.handler(socket, request, ctx);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
failed({ pattern: match.pattern, plugin: match.plugin, error });
|
|
57
|
+
socket.close(1011, "internal error");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!closed.signal.aborted) {
|
|
61
|
+
await new Promise((resolve) => closed.signal.addEventListener("abort", resolve, { once: true }));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// The scope sealed (its socket closed, the host closing) is no failure of the handler.
|
|
65
|
+
void host.root(run, scope, { principal }).catch(() => { });
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The router changed: connections through a host or a relay no longer there, and plugin sockets whose handler left,
|
|
70
|
+
* are terminated at once and their scopes sealed (no close handshake a peer could ignore).
|
|
71
|
+
*/
|
|
72
|
+
revoke(router) {
|
|
73
|
+
for (const upgraded of this.#open) {
|
|
74
|
+
const gone = (upgraded.allowed !== undefined && !router.hosts.has(upgraded.allowed)) ||
|
|
75
|
+
(upgraded.relay !== undefined && !router.relays.includes(upgraded.relay)) ||
|
|
76
|
+
(upgraded.handler !== undefined && !router.socketHandlers.has(upgraded.handler));
|
|
77
|
+
if (gone)
|
|
78
|
+
end(upgraded);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Closes every connection (1001, "going away"); those still open at `deadline` are terminated. */
|
|
82
|
+
async close(deadline) {
|
|
83
|
+
const open = [...this.#open];
|
|
84
|
+
const closed = open.map(({ socket }) => new Promise((resolve) => {
|
|
85
|
+
if (socket.readyState === socket.CLOSED)
|
|
86
|
+
resolve();
|
|
87
|
+
else
|
|
88
|
+
socket.once("close", () => resolve());
|
|
89
|
+
}));
|
|
90
|
+
for (const { socket } of open)
|
|
91
|
+
socket.close(1001, "going away");
|
|
92
|
+
await Promise.race([Promise.all(closed), deadline]);
|
|
93
|
+
for (const upgraded of this.#open)
|
|
94
|
+
end(upgraded);
|
|
95
|
+
}
|
|
96
|
+
/** Keeps `upgraded` until its socket closes, letting a protocol error finish its close handshake. */
|
|
97
|
+
#keep(upgraded) {
|
|
98
|
+
const { socket } = upgraded;
|
|
99
|
+
socket.on("error", () => {
|
|
100
|
+
// ws already sends the protocol close code (such as 1009); terminating now can discard that frame.
|
|
101
|
+
if (socket.readyState !== socket.CLOSING)
|
|
102
|
+
socket.terminate();
|
|
103
|
+
});
|
|
104
|
+
this.#open.add(upgraded);
|
|
105
|
+
socket.once("close", () => this.#open.delete(upgraded));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Completes the upgrade with a `ws` server of its own (no listener, no client tracking, no compression), dropped with
|
|
110
|
+
* the upgrade: nothing is kept per frame size.
|
|
111
|
+
*/
|
|
112
|
+
function upgrade(message, stream, head, maxPayload, then) {
|
|
113
|
+
const server = new WebSocketServer({ noServer: true, clientTracking: false, maxPayload, perMessageDeflate: false });
|
|
114
|
+
server.handleUpgrade(message, stream, head, then);
|
|
115
|
+
}
|
|
116
|
+
/** Terminates `upgraded` and seals its scope at once. */
|
|
117
|
+
function end(upgraded) {
|
|
118
|
+
// Terminated first: a link's close would send a close frame.
|
|
119
|
+
upgraded.socket.terminate();
|
|
120
|
+
upgraded.seal();
|
|
121
|
+
}
|
|
122
|
+
/** Silence after which a plugin socket is pinged, and after the ping terminated: 15 s each (the link heartbeat's). */
|
|
123
|
+
const SILENCE = 15_000;
|
|
124
|
+
/**
|
|
125
|
+
* Keeps a plugin socket honest (decision "plugin sockets get a heartbeat"): after 15 s without a frame from the peer it
|
|
126
|
+
* is pinged, after 15 s more terminated; browsers and `ws` answer pings by themselves.
|
|
127
|
+
*/
|
|
128
|
+
function heartbeat(socket) {
|
|
129
|
+
let pinged = false;
|
|
130
|
+
const timer = setTimeout(() => {
|
|
131
|
+
if (pinged) {
|
|
132
|
+
socket.terminate();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
pinged = true;
|
|
136
|
+
socket.ping();
|
|
137
|
+
timer.refresh();
|
|
138
|
+
}, SILENCE);
|
|
139
|
+
timer.unref();
|
|
140
|
+
const heard = () => {
|
|
141
|
+
pinged = false;
|
|
142
|
+
timer.refresh();
|
|
143
|
+
};
|
|
144
|
+
socket.on("message", heard);
|
|
145
|
+
socket.on("pong", heard);
|
|
146
|
+
socket.on("ping", heard);
|
|
147
|
+
socket.once("close", () => clearTimeout(timer));
|
|
148
|
+
}
|
|
149
|
+
/** Unsent data beyond the frame being sent at which a link socket is cut off: a client that stopped reading. */
|
|
150
|
+
const MAX_UNSENT_BYTES = 4 * 1024 * 1024;
|
|
151
|
+
/**
|
|
152
|
+
* `socket` as the link sees it, its output capped (p2's `limitedSocket`): before each send, what is still buffered
|
|
153
|
+
* beyond the largest frame being sent must stay under 4 MiB, or the socket is terminated (the client reconnects from
|
|
154
|
+
* snapshots); Chord's flow control keeps a reading client far below it.
|
|
155
|
+
*/
|
|
156
|
+
export function limitedSocket(socket) {
|
|
157
|
+
const unsent = new Set();
|
|
158
|
+
return {
|
|
159
|
+
get readyState() {
|
|
160
|
+
return socket.readyState;
|
|
161
|
+
},
|
|
162
|
+
get binaryType() {
|
|
163
|
+
return socket.binaryType;
|
|
164
|
+
},
|
|
165
|
+
set binaryType(type) {
|
|
166
|
+
socket.binaryType = type;
|
|
167
|
+
},
|
|
168
|
+
send(data) {
|
|
169
|
+
if (socket.readyState !== socket.OPEN)
|
|
170
|
+
return;
|
|
171
|
+
let sending = 0;
|
|
172
|
+
for (const frame of unsent)
|
|
173
|
+
sending = Math.max(sending, frame.bytes);
|
|
174
|
+
if (socket.bufferedAmount - sending > MAX_UNSENT_BYTES) {
|
|
175
|
+
socket.terminate();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// The largest server frame header is 10 bytes.
|
|
179
|
+
const frame = { bytes: data.byteLength + 10 };
|
|
180
|
+
unsent.add(frame);
|
|
181
|
+
socket.send(data, (error) => {
|
|
182
|
+
unsent.delete(frame);
|
|
183
|
+
if (error)
|
|
184
|
+
socket.terminate();
|
|
185
|
+
});
|
|
186
|
+
},
|
|
187
|
+
close: () => socket.close(),
|
|
188
|
+
addEventListener: (type, listener) => socket.addEventListener(type, listener),
|
|
189
|
+
removeEventListener: (type, listener) => socket.removeEventListener(type, listener),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=upgrades.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrades.js","sourceRoot":"","sources":["../../../src/node/http/upgrades.ts"],"names":[],"mappings":"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","sourcesContent":["// Upgraded connections (slice 10 §2, D6, Q6): the links endpoint (`host.accept` over a WebSocket with a per-socket\n// output cap) and plugin sockets (a `ws` WebSocket handed to the contribution's handler for its own protocol, in a scope\n// lasting until it closes, kept alive by a heartbeat). Each connection is kept with what admitted it: when that leaves\n// (its allowed host, its relay, its socket handler) it is terminated at once and its scope sealed (decision \"Slice 10\n// fix round, allowed hosts only through contributions\"); the component's close closes all (1001), terminating at its\n// timeout those that never acknowledge.\n\nimport type { IncomingMessage } from \"node:http\";\nimport type { Duplex } from \"node:stream\";\nimport { type WebSocket, WebSocketServer } from \"ws\";\nimport { type Context, withAbortSignal, withoutAbortSignal } from \"../../context/index.ts\";\nimport type { Principal } from \"../../data/index.ts\";\nimport type { Ctx, Host } from \"../../host/index.ts\";\nimport { type PartLimits, type WebSocketLike, webSocketLink } from \"../../link/index.ts\";\nimport type { HttpRequest } from \"./request.ts\";\nimport type { HttpRelay, HttpSocket, Router, SocketMatch } from \"./router.ts\";\n\n/** What admitted an upgrade: the allowed host or the relay it came through (local: neither), and its principal. */\nexport type Admission<P extends Principal> = {\n\treadonly allowed: string | undefined;\n\treadonly relay: HttpRelay | undefined;\n\treadonly principal: P;\n};\n\n/** What the links endpoint gives one socket: its parts' limits and its largest frame (1 MiB by default). */\nexport type LinkOptions = { readonly limits?: PartLimits; readonly maxPayload?: number };\n\n/** A plugin socket's handler failed: reported, the socket closed (1011). */\nexport type SocketFailure = { readonly pattern: string; readonly plugin: string; readonly error: unknown };\n\n/** One upgraded connection, with what admitted it and how to seal its scope. */\ntype Upgraded = {\n\treadonly socket: WebSocket;\n\treadonly allowed: string | undefined;\n\treadonly relay: HttpRelay | undefined;\n\t/** The handler that took it (plugin sockets only). */\n\treadonly handler: HttpSocket | undefined;\n\t/** Ends its work at once: the link closed, or the handler's scope sealed. */\n\treadonly seal: () => void;\n};\n\n/** A link socket's largest frame unless `links.options` says otherwise: 1 MiB. */\nconst DEFAULT_LINK_PAYLOAD = 1024 * 1024;\n\n/** The upgraded connections of one HTTP component. */\nexport class Upgrades {\n\treadonly #open = new Set<Upgraded>();\n\n\t/**\n\t * Upgrades `message` to the links endpoint: `host.accept` over the socket (its output capped) as the admitted\n\t * principal, with `options`' limits; `context` is the parent of the work on the link. `opened` runs once the link\n\t * is accepted; what it returns runs when its socket closes.\n\t */\n\tlink<P extends Principal>(\n\t\tmessage: IncomingMessage,\n\t\tstream: Duplex,\n\t\thead: Buffer,\n\t\tadmission: Admission<P> & LinkOptions,\n\t\thost: Host<P>,\n\t\tcontext: Context,\n\t\topened: () => (() => void) | undefined,\n\t): void {\n\t\tconst { principal, limits } = admission;\n\t\tupgrade(message, stream, head, admission.maxPayload ?? DEFAULT_LINK_PAYLOAD, (socket) => {\n\t\t\tconst link = webSocketLink(limitedSocket(socket));\n\t\t\tthis.#keep({\n\t\t\t\tsocket,\n\t\t\t\tallowed: admission.allowed,\n\t\t\t\trelay: admission.relay,\n\t\t\t\thandler: undefined,\n\t\t\t\tseal: () => link.close(),\n\t\t\t});\n\t\t\thost.accept(link, { principal, ...(limits === undefined ? {} : { limits }) }, context);\n\t\t\tconst closed = opened();\n\t\t\tif (closed !== undefined) socket.once(\"close\", closed);\n\t\t});\n\t}\n\n\t/**\n\t * Upgrades `message` to the plugin socket `match`: its handler gets the socket and `request` in a `host.root` scope\n\t * acting as the admitted principal that lasts until the socket closes; a handler that throws is reported and closes\n\t * it (1011).\n\t */\n\tsocket<P extends Principal>(\n\t\tmessage: IncomingMessage,\n\t\tstream: Duplex,\n\t\thead: Buffer,\n\t\tadmission: Omit<Admission<P>, \"principal\"> & {\n\t\t\t/** Anonymous only for a public socket. */\n\t\t\treadonly principal: P | undefined;\n\t\t\treadonly match: SocketMatch;\n\t\t\treadonly request: HttpRequest;\n\t\t},\n\t\thost: Host<P>,\n\t\tcontext: Context,\n\t\tfailed: (failure: SocketFailure) => void,\n\t): void {\n\t\tconst { principal, match, request } = admission;\n\t\tupgrade(message, stream, head, match.maxPayload, (socket) => {\n\t\t\tconst closed = new AbortController();\n\t\t\tconst seal = (): void => closed.abort(new Error(\"http: the socket closed\"));\n\t\t\tsocket.once(\"close\", seal);\n\t\t\tthis.#keep({ socket, allowed: admission.allowed, relay: admission.relay, handler: match.handler, seal });\n\t\t\theartbeat(socket);\n\t\t\tconst scope = withAbortSignal(closed.signal, withoutAbortSignal(context));\n\t\t\tconst run = async (ctx: Ctx<P>): Promise<void> => {\n\t\t\t\ttry {\n\t\t\t\t\tawait match.handler(socket, request, ctx);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailed({ pattern: match.pattern, plugin: match.plugin, error });\n\t\t\t\t\tsocket.close(1011, \"internal error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!closed.signal.aborted) {\n\t\t\t\t\tawait new Promise((resolve) => closed.signal.addEventListener(\"abort\", resolve, { once: true }));\n\t\t\t\t}\n\t\t\t};\n\t\t\t// The scope sealed (its socket closed, the host closing) is no failure of the handler.\n\t\t\tvoid host.root(run, scope, { principal }).catch(() => {});\n\t\t});\n\t}\n\n\t/**\n\t * The router changed: connections through a host or a relay no longer there, and plugin sockets whose handler left,\n\t * are terminated at once and their scopes sealed (no close handshake a peer could ignore).\n\t */\n\trevoke(router: Router): void {\n\t\tfor (const upgraded of this.#open) {\n\t\t\tconst gone =\n\t\t\t\t(upgraded.allowed !== undefined && !router.hosts.has(upgraded.allowed)) ||\n\t\t\t\t(upgraded.relay !== undefined && !router.relays.includes(upgraded.relay)) ||\n\t\t\t\t(upgraded.handler !== undefined && !router.socketHandlers.has(upgraded.handler));\n\t\t\tif (gone) end(upgraded);\n\t\t}\n\t}\n\n\t/** Closes every connection (1001, \"going away\"); those still open at `deadline` are terminated. */\n\tasync close(deadline: Promise<void>): Promise<void> {\n\t\tconst open = [...this.#open];\n\t\tconst closed = open.map(\n\t\t\t({ socket }) =>\n\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\tif (socket.readyState === socket.CLOSED) resolve();\n\t\t\t\t\telse socket.once(\"close\", () => resolve());\n\t\t\t\t}),\n\t\t);\n\t\tfor (const { socket } of open) socket.close(1001, \"going away\");\n\t\tawait Promise.race([Promise.all(closed), deadline]);\n\t\tfor (const upgraded of this.#open) end(upgraded);\n\t}\n\n\t/** Keeps `upgraded` until its socket closes, letting a protocol error finish its close handshake. */\n\t#keep(upgraded: Upgraded): void {\n\t\tconst { socket } = upgraded;\n\t\tsocket.on(\"error\", () => {\n\t\t\t// ws already sends the protocol close code (such as 1009); terminating now can discard that frame.\n\t\t\tif (socket.readyState !== socket.CLOSING) socket.terminate();\n\t\t});\n\t\tthis.#open.add(upgraded);\n\t\tsocket.once(\"close\", () => this.#open.delete(upgraded));\n\t}\n}\n\n/**\n * Completes the upgrade with a `ws` server of its own (no listener, no client tracking, no compression), dropped with\n * the upgrade: nothing is kept per frame size.\n */\nfunction upgrade(\n\tmessage: IncomingMessage,\n\tstream: Duplex,\n\thead: Buffer,\n\tmaxPayload: number,\n\tthen: (socket: WebSocket) => void,\n): void {\n\tconst server = new WebSocketServer({ noServer: true, clientTracking: false, maxPayload, perMessageDeflate: false });\n\tserver.handleUpgrade(message, stream, head, then);\n}\n\n/** Terminates `upgraded` and seals its scope at once. */\nfunction end(upgraded: Upgraded): void {\n\t// Terminated first: a link's close would send a close frame.\n\tupgraded.socket.terminate();\n\tupgraded.seal();\n}\n\n/** Silence after which a plugin socket is pinged, and after the ping terminated: 15 s each (the link heartbeat's). */\nconst SILENCE = 15_000;\n\n/**\n * Keeps a plugin socket honest (decision \"plugin sockets get a heartbeat\"): after 15 s without a frame from the peer it\n * is pinged, after 15 s more terminated; browsers and `ws` answer pings by themselves.\n */\nfunction heartbeat(socket: WebSocket): void {\n\tlet pinged = false;\n\tconst timer = setTimeout(() => {\n\t\tif (pinged) {\n\t\t\tsocket.terminate();\n\t\t\treturn;\n\t\t}\n\t\tpinged = true;\n\t\tsocket.ping();\n\t\ttimer.refresh();\n\t}, SILENCE);\n\ttimer.unref();\n\tconst heard = (): void => {\n\t\tpinged = false;\n\t\ttimer.refresh();\n\t};\n\tsocket.on(\"message\", heard);\n\tsocket.on(\"pong\", heard);\n\tsocket.on(\"ping\", heard);\n\tsocket.once(\"close\", () => clearTimeout(timer));\n}\n\n/** Unsent data beyond the frame being sent at which a link socket is cut off: a client that stopped reading. */\nconst MAX_UNSENT_BYTES = 4 * 1024 * 1024;\n\n/**\n * `socket` as the link sees it, its output capped (p2's `limitedSocket`): before each send, what is still buffered\n * beyond the largest frame being sent must stay under 4 MiB, or the socket is terminated (the client reconnects from\n * snapshots); Chord's flow control keeps a reading client far below it.\n */\nexport function limitedSocket(socket: WebSocket): WebSocketLike {\n\tconst unsent = new Set<{ readonly bytes: number }>();\n\treturn {\n\t\tget readyState() {\n\t\t\treturn socket.readyState;\n\t\t},\n\t\tget binaryType() {\n\t\t\treturn socket.binaryType;\n\t\t},\n\t\tset binaryType(type: string) {\n\t\t\tsocket.binaryType = type as WebSocket[\"binaryType\"];\n\t\t},\n\t\tsend(data) {\n\t\t\tif (socket.readyState !== socket.OPEN) return;\n\t\t\tlet sending = 0;\n\t\t\tfor (const frame of unsent) sending = Math.max(sending, frame.bytes);\n\t\t\tif (socket.bufferedAmount - sending > MAX_UNSENT_BYTES) {\n\t\t\t\tsocket.terminate();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// The largest server frame header is 10 bytes.\n\t\t\tconst frame = { bytes: data.byteLength + 10 };\n\t\t\tunsent.add(frame);\n\t\t\tsocket.send(data, (error) => {\n\t\t\t\tunsent.delete(frame);\n\t\t\t\tif (error) socket.terminate();\n\t\t\t});\n\t\t},\n\t\tclose: () => socket.close(),\n\t\taddEventListener: (type: string, listener: (event: { readonly data: unknown }) => void) =>\n\t\t\tsocket.addEventListener(type as \"message\", listener as never),\n\t\tremoveEventListener: (type: string, listener: (event: { readonly data: unknown }) => void) =>\n\t\t\tsocket.removeEventListener(type as \"message\", listener as never),\n\t} as WebSocketLike;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
/** What a base artifact was built from: the hash of each file's bytes as read (`contentHash`), by absolute path. */
|
|
3
|
+
export type BaseInputs = ReadonlyMap<string, string>;
|
|
4
|
+
/** The hash of `bytes` a base record keeps (SHA-256, hex). */
|
|
5
|
+
export declare function contentHash(bytes: Uint8Array): string;
|
|
6
|
+
/** Reads `path` for a build, recording its bytes' hash in `inputs`: the one read of the file, its bytes for esbuild. */
|
|
7
|
+
export declare function readRecorded(path: string, inputs: Map<string, string>): Promise<Buffer>;
|
|
8
|
+
/**
|
|
9
|
+
* An esbuild plugin loading every file through `readRecorded`, with esbuild's own loader for its extension: what the
|
|
10
|
+
* build read, in `inputs`. The last of a build's plugins: an earlier `onLoad` returning contents reads (and records)
|
|
11
|
+
* the file itself.
|
|
12
|
+
*/
|
|
13
|
+
export declare function recordedSources(inputs: Map<string, string>): Plugin;
|
|
14
|
+
//# sourceMappingURL=base-inputs.d.ts.map
|