@lunora/runtime 1.0.0-alpha.3 → 1.0.0-alpha.5

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/dist/index.d.mts CHANGED
@@ -420,6 +420,14 @@ declare const emitRpcEvent: (sink: ObservabilitySink | undefined, event: Observa
420
420
  */
421
421
  declare const emitLogEvent: (sink: ObservabilitySink | undefined, event: LogEvent, context?: ObservabilitySinkContext) => void;
422
422
  /**
423
+ * Cloudflare Durable Object jurisdictions restrict where a DO runs and persists
424
+ * data, for data-residency / compliance regimes (GDPR, FedRAMP, US data
425
+ * residency). The set is open — Cloudflare adds values over time — so this is a
426
+ * widening union rather than a closed enum.
427
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
428
+ */
429
+ type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
430
+ /**
423
431
  * Structural projection of the bits of `DurableObjectNamespace` the runtime
424
432
  * needs. Real workers-types defines a much wider surface; this lets us pass
425
433
  * unit-test doubles without coupling to `@cloudflare/workers-types`.
@@ -437,10 +445,29 @@ interface ShardNamespaceLike {
437
445
  fetch: (request: Request) => Promise<Response>;
438
446
  };
439
447
  idFromName: (name: string) => unknown;
448
+ /**
449
+ * Derive a jurisdiction-restricted subnamespace. Every ID and stub created
450
+ * from the returned namespace is pinned to `jurisdiction`. Optional because
451
+ * older workers-types releases (and unit-test doubles) may not expose it;
452
+ * {@link applyJurisdiction} fails closed when a jurisdiction is requested
453
+ * but this method is absent.
454
+ */
455
+ jurisdiction?: (jurisdiction: DurableObjectJurisdiction) => ShardNamespaceLike;
440
456
  }
441
457
  interface ResolvedShard {
442
458
  fetch: (request: Request) => Promise<Response>;
443
459
  }
460
+ /**
461
+ * Return a jurisdiction-restricted view of `namespace`, or `namespace`
462
+ * unchanged when no jurisdiction is configured.
463
+ *
464
+ * Fail-closed: if a jurisdiction is requested but the binding does not expose
465
+ * `.jurisdiction()` (an older workers-types, or a misconfigured test double),
466
+ * this throws rather than silently routing to the un-pinned global namespace —
467
+ * silently dropping a residency constraint would let data land outside the
468
+ * compliance boundary the caller asked for.
469
+ */
470
+ declare const applyJurisdiction: (namespace: ShardNamespaceLike, jurisdiction?: DurableObjectJurisdiction) => ShardNamespaceLike;
444
471
  /** Look up a shard stub by name, preferring `getByName` when present. */
445
472
  declare const resolveShard: (namespace: ShardNamespaceLike, shardKey: string) => ResolvedShard;
446
473
  /**
@@ -1472,6 +1499,12 @@ interface ScheduledControllerLike {
1472
1499
  */
1473
1500
  type CronHandler = (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void> | void;
1474
1501
  /**
1502
+ * A Cloudflare Queues push-consumer handler — the worker's `queue()` entry
1503
+ * forwards each delivered `MessageBatch` (typed `unknown` here to keep the
1504
+ * runtime decoupled from `@lunora/queue`'s structural batch type).
1505
+ */
1506
+ type QueueConsumerHandler = (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1507
+ /**
1475
1508
  * A single code-defined cron job, shaped like an entry of the generated
1476
1509
  * `LUNORA_CRONS` map. `functionPath` is the `"namespace:fn"` to run, `args` its
1477
1510
  * bound arguments, and `name` the human label from the `cronJobs()` builder.
@@ -1742,6 +1775,27 @@ interface WorkerOptions {
1742
1775
  */
1743
1776
  importGlobals?: GlobalImportFunction;
1744
1777
  /**
1778
+ * Restrict every Durable Object this worker reaches — shard DOs, the
1779
+ * scheduler DO, the fan-out coordinator, subscriptions — to a Cloudflare
1780
+ * data-residency jurisdiction (`"eu"`, `"us"`, `"fedramp"`). The runtime
1781
+ * derives a jurisdiction-pinned subnamespace from {@link WorkerOptions.shardDO}
1782
+ * and {@link WorkerOptions.schedulerDO} once, so all routing inherits it.
1783
+ *
1784
+ * Fail-closed: if the bound namespace does not expose `.jurisdiction()`
1785
+ * (an older `@cloudflare/workers-types`), the worker throws rather than
1786
+ * silently routing to the un-pinned global namespace. Omit it for the
1787
+ * default, un-pinned behaviour.
1788
+ *
1789
+ * ⚠️ Set once, before the first deploy — changing it strands data. A DO name
1790
+ * maps to a *different* ID per jurisdiction, so toggling this on an existing
1791
+ * deployment makes every shard/scheduler call resolve to a new, empty DO; the
1792
+ * prior data stays in the old jurisdiction and is unreachable (no in-place
1793
+ * migration). Usually set via the schema's `.jurisdiction(...)`, which codegen
1794
+ * threads here.
1795
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
1796
+ */
1797
+ jurisdiction?: DurableObjectJurisdiction;
1798
+ /**
1745
1799
  * Optional telemetry sink. When supplied, the worker emits one
1746
1800
  * `onRpc` event per dispatched RPC (single-shard forward or fan-out)
1747
1801
  * with duration / ok / error / shardKey or fanOut metadata. Sink
@@ -1796,6 +1850,14 @@ interface WorkerOptions {
1796
1850
  */
1797
1851
  queryCoordinator?: QueryCoordinator;
1798
1852
  /**
1853
+ * Cloudflare Queues push-consumer handler — the worker's `queue(batch, …)`
1854
+ * entry forwards every delivered `MessageBatch` here. Built by codegen from
1855
+ * `lunora/queues.ts` (via `@lunora/queue`'s `dispatchQueueBatch`, which routes
1856
+ * by `batch.queue` to the matching `defineQueue` handler), so the runtime
1857
+ * stays decoupled from the queue package. Omitted when no push queues exist.
1858
+ */
1859
+ queue?: QueueConsumerHandler;
1860
+ /**
1799
1861
  * Resolve the calling identity from the inbound RPC request. Called once
1800
1862
  * per RPC (and per fan-out) before the request is forwarded to the
1801
1863
  * shard. The returned `userId` becomes `ctx.auth.userId` on the shard
@@ -1918,6 +1980,12 @@ interface RpcContext {
1918
1980
  */
1919
1981
  interface LunoraWorker {
1920
1982
  fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response>;
1983
+ /**
1984
+ * Cloudflare Queues consumer entry — present only when the app declares push
1985
+ * queues. Forwards each delivered `MessageBatch` to the configured
1986
+ * {@link WorkerOptions.queue} handler; a no-op when none is set.
1987
+ */
1988
+ queue?: (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1921
1989
  scheduled: (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void>;
1922
1990
  /**
1923
1991
  * In-process query/mutation dispatch for SSR loaders co-located in this
@@ -2082,6 +2150,12 @@ interface DynamicShardRegistryOptions {
2082
2150
  * only if you run multiple isolated registries in one environment.
2083
2151
  */
2084
2152
  instanceName?: string;
2153
+ /**
2154
+ * Pin the registry DO to a Cloudflare data-residency jurisdiction. Pass the
2155
+ * same value as the worker's `jurisdiction` so the registry co-locates with
2156
+ * the shards it tracks. Omit for the un-pinned global namespace.
2157
+ */
2158
+ jurisdiction?: DurableObjectJurisdiction;
2085
2159
  /** DO namespace binding (`env.SHARD_REGISTRY`). */
2086
2160
  namespace: ShardNamespaceLike;
2087
2161
  }
@@ -2256,4 +2330,4 @@ declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => Obse
2256
2330
  */
2257
2331
  declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink;
2258
2332
  declare const VERSION: string;
2259
- export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type BackupManifest, type BackupStore, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type ImportFanOutRequest, type ImportFanOutResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, combineSinks, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveSecurity, resolveShard, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
2333
+ export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type BackupManifest, type BackupStore, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type ImportFanOutRequest, type ImportFanOutResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveSecurity, resolveShard, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
package/dist/index.d.ts CHANGED
@@ -420,6 +420,14 @@ declare const emitRpcEvent: (sink: ObservabilitySink | undefined, event: Observa
420
420
  */
421
421
  declare const emitLogEvent: (sink: ObservabilitySink | undefined, event: LogEvent, context?: ObservabilitySinkContext) => void;
422
422
  /**
423
+ * Cloudflare Durable Object jurisdictions restrict where a DO runs and persists
424
+ * data, for data-residency / compliance regimes (GDPR, FedRAMP, US data
425
+ * residency). The set is open — Cloudflare adds values over time — so this is a
426
+ * widening union rather than a closed enum.
427
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
428
+ */
429
+ type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
430
+ /**
423
431
  * Structural projection of the bits of `DurableObjectNamespace` the runtime
424
432
  * needs. Real workers-types defines a much wider surface; this lets us pass
425
433
  * unit-test doubles without coupling to `@cloudflare/workers-types`.
@@ -437,10 +445,29 @@ interface ShardNamespaceLike {
437
445
  fetch: (request: Request) => Promise<Response>;
438
446
  };
439
447
  idFromName: (name: string) => unknown;
448
+ /**
449
+ * Derive a jurisdiction-restricted subnamespace. Every ID and stub created
450
+ * from the returned namespace is pinned to `jurisdiction`. Optional because
451
+ * older workers-types releases (and unit-test doubles) may not expose it;
452
+ * {@link applyJurisdiction} fails closed when a jurisdiction is requested
453
+ * but this method is absent.
454
+ */
455
+ jurisdiction?: (jurisdiction: DurableObjectJurisdiction) => ShardNamespaceLike;
440
456
  }
441
457
  interface ResolvedShard {
442
458
  fetch: (request: Request) => Promise<Response>;
443
459
  }
460
+ /**
461
+ * Return a jurisdiction-restricted view of `namespace`, or `namespace`
462
+ * unchanged when no jurisdiction is configured.
463
+ *
464
+ * Fail-closed: if a jurisdiction is requested but the binding does not expose
465
+ * `.jurisdiction()` (an older workers-types, or a misconfigured test double),
466
+ * this throws rather than silently routing to the un-pinned global namespace —
467
+ * silently dropping a residency constraint would let data land outside the
468
+ * compliance boundary the caller asked for.
469
+ */
470
+ declare const applyJurisdiction: (namespace: ShardNamespaceLike, jurisdiction?: DurableObjectJurisdiction) => ShardNamespaceLike;
444
471
  /** Look up a shard stub by name, preferring `getByName` when present. */
445
472
  declare const resolveShard: (namespace: ShardNamespaceLike, shardKey: string) => ResolvedShard;
446
473
  /**
@@ -1472,6 +1499,12 @@ interface ScheduledControllerLike {
1472
1499
  */
1473
1500
  type CronHandler = (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void> | void;
1474
1501
  /**
1502
+ * A Cloudflare Queues push-consumer handler — the worker's `queue()` entry
1503
+ * forwards each delivered `MessageBatch` (typed `unknown` here to keep the
1504
+ * runtime decoupled from `@lunora/queue`'s structural batch type).
1505
+ */
1506
+ type QueueConsumerHandler = (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1507
+ /**
1475
1508
  * A single code-defined cron job, shaped like an entry of the generated
1476
1509
  * `LUNORA_CRONS` map. `functionPath` is the `"namespace:fn"` to run, `args` its
1477
1510
  * bound arguments, and `name` the human label from the `cronJobs()` builder.
@@ -1742,6 +1775,27 @@ interface WorkerOptions {
1742
1775
  */
1743
1776
  importGlobals?: GlobalImportFunction;
1744
1777
  /**
1778
+ * Restrict every Durable Object this worker reaches — shard DOs, the
1779
+ * scheduler DO, the fan-out coordinator, subscriptions — to a Cloudflare
1780
+ * data-residency jurisdiction (`"eu"`, `"us"`, `"fedramp"`). The runtime
1781
+ * derives a jurisdiction-pinned subnamespace from {@link WorkerOptions.shardDO}
1782
+ * and {@link WorkerOptions.schedulerDO} once, so all routing inherits it.
1783
+ *
1784
+ * Fail-closed: if the bound namespace does not expose `.jurisdiction()`
1785
+ * (an older `@cloudflare/workers-types`), the worker throws rather than
1786
+ * silently routing to the un-pinned global namespace. Omit it for the
1787
+ * default, un-pinned behaviour.
1788
+ *
1789
+ * ⚠️ Set once, before the first deploy — changing it strands data. A DO name
1790
+ * maps to a *different* ID per jurisdiction, so toggling this on an existing
1791
+ * deployment makes every shard/scheduler call resolve to a new, empty DO; the
1792
+ * prior data stays in the old jurisdiction and is unreachable (no in-place
1793
+ * migration). Usually set via the schema's `.jurisdiction(...)`, which codegen
1794
+ * threads here.
1795
+ * @see https://developers.cloudflare.com/durable-objects/reference/data-location/
1796
+ */
1797
+ jurisdiction?: DurableObjectJurisdiction;
1798
+ /**
1745
1799
  * Optional telemetry sink. When supplied, the worker emits one
1746
1800
  * `onRpc` event per dispatched RPC (single-shard forward or fan-out)
1747
1801
  * with duration / ok / error / shardKey or fanOut metadata. Sink
@@ -1796,6 +1850,14 @@ interface WorkerOptions {
1796
1850
  */
1797
1851
  queryCoordinator?: QueryCoordinator;
1798
1852
  /**
1853
+ * Cloudflare Queues push-consumer handler — the worker's `queue(batch, …)`
1854
+ * entry forwards every delivered `MessageBatch` here. Built by codegen from
1855
+ * `lunora/queues.ts` (via `@lunora/queue`'s `dispatchQueueBatch`, which routes
1856
+ * by `batch.queue` to the matching `defineQueue` handler), so the runtime
1857
+ * stays decoupled from the queue package. Omitted when no push queues exist.
1858
+ */
1859
+ queue?: QueueConsumerHandler;
1860
+ /**
1799
1861
  * Resolve the calling identity from the inbound RPC request. Called once
1800
1862
  * per RPC (and per fan-out) before the request is forwarded to the
1801
1863
  * shard. The returned `userId` becomes `ctx.auth.userId` on the shard
@@ -1918,6 +1980,12 @@ interface RpcContext {
1918
1980
  */
1919
1981
  interface LunoraWorker {
1920
1982
  fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response>;
1983
+ /**
1984
+ * Cloudflare Queues consumer entry — present only when the app declares push
1985
+ * queues. Forwards each delivered `MessageBatch` to the configured
1986
+ * {@link WorkerOptions.queue} handler; a no-op when none is set.
1987
+ */
1988
+ queue?: (batch: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
1921
1989
  scheduled: (controller: ScheduledControllerLike, env: unknown, context: ExecutionContextLike) => Promise<void>;
1922
1990
  /**
1923
1991
  * In-process query/mutation dispatch for SSR loaders co-located in this
@@ -2082,6 +2150,12 @@ interface DynamicShardRegistryOptions {
2082
2150
  * only if you run multiple isolated registries in one environment.
2083
2151
  */
2084
2152
  instanceName?: string;
2153
+ /**
2154
+ * Pin the registry DO to a Cloudflare data-residency jurisdiction. Pass the
2155
+ * same value as the worker's `jurisdiction` so the registry co-locates with
2156
+ * the shards it tracks. Omit for the un-pinned global namespace.
2157
+ */
2158
+ jurisdiction?: DurableObjectJurisdiction;
2085
2159
  /** DO namespace binding (`env.SHARD_REGISTRY`). */
2086
2160
  namespace: ShardNamespaceLike;
2087
2161
  }
@@ -2256,4 +2330,4 @@ declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => Obse
2256
2330
  */
2257
2331
  declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink;
2258
2332
  declare const VERSION: string;
2259
- export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type BackupManifest, type BackupStore, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type ImportFanOutRequest, type ImportFanOutResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, combineSinks, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveSecurity, resolveShard, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
2333
+ export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type BackupManifest, type BackupStore, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type ImportFanOutRequest, type ImportFanOutResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveSecurity, resolveShard, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
package/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  export { toAirbyteMessages, toFivetranResponse } from './packem_shared/toAirbyteMessages-DrHdplb4.mjs';
2
- export { composeWorker, createWorker, defineRpcEnvelope, withFrameworkWorker } from './packem_shared/composeWorker-CjF1xUIO.mjs';
2
+ export { composeWorker, createWorker, defineRpcEnvelope, withFrameworkWorker } from './packem_shared/composeWorker-49Hxp9Ho.mjs';
3
3
  export { createCrossShardRelationCapabilities } from './packem_shared/createCrossShardRelationCapabilities-C0KOf7er.mjs';
4
- export { DEFAULT_REGISTRY_CACHE_TTL_MS, SHARD_REGISTRY_DO_NAME, createDynamicShardRegistry } from './packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-BpCwo_mo.mjs';
4
+ export { DEFAULT_REGISTRY_CACHE_TTL_MS, SHARD_REGISTRY_DO_NAME, createDynamicShardRegistry } from './packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-ocax8v0n.mjs';
5
5
  export { LunoraError, toErrorResponse } from './packem_shared/LunoraError-CL0aOtpo.mjs';
6
6
  export { emitLogEvent, emitRpcEvent } from './packem_shared/emitLogEvent-pEdtqAK8.mjs';
7
7
  export { analyticsEngineSink, combineSinks, consoleSink, sentrySink, webhookSink } from './packem_shared/analyticsEngineSink-DqEvrQs0.mjs';
8
- export { createQueryCoordinator, createStaticShardRegistry, mergeStrategyForAggregate } from './packem_shared/createQueryCoordinator-DbxC7iUz.mjs';
9
- export { resolveShard } from './packem_shared/resolveShard-DDkzWtrU.mjs';
8
+ export { createQueryCoordinator, createStaticShardRegistry, mergeStrategyForAggregate } from './packem_shared/createQueryCoordinator-Cbds9cUI.mjs';
9
+ export { applyJurisdiction, resolveShard } from './packem_shared/applyJurisdiction-BkZtTkct.mjs';
10
10
  export { decorateResponse, enforceOrigin, handleCorsPreflight, resolveSecurity } from './packem_shared/decorateResponse-DbISh_Wi.mjs';
11
11
 
12
12
  const VERSION = "0.0.0";
@@ -1,3 +1,5 @@
1
+ import { applyJurisdiction } from './applyJurisdiction-BkZtTkct.mjs';
2
+
1
3
  const SHARD_REGISTRY_DO_NAME = "__lunora_shard_registry__";
2
4
  const DEFAULT_REGISTRY_CACHE_TTL_MS = 3e4;
3
5
  const REGISTRY_BASE_URL = "https://shard-registry.internal";
@@ -10,9 +12,10 @@ const createDynamicShardRegistry = (options) => {
10
12
  const instanceName = options.instanceName ?? SHARD_REGISTRY_DO_NAME;
11
13
  const cacheTtlMs = options.cacheTtlMs ?? DEFAULT_REGISTRY_CACHE_TTL_MS;
12
14
  const cache = /* @__PURE__ */ new Map();
15
+ const namespace = applyJurisdiction(options.namespace, options.jurisdiction);
13
16
  let cachedStub;
14
17
  const stub = () => {
15
- cachedStub ??= options.namespace.get(options.namespace.idFromName(instanceName));
18
+ cachedStub ??= namespace.get(namespace.idFromName(instanceName));
16
19
  return cachedStub;
17
20
  };
18
21
  const post = async (path, body) => stub().fetch(
@@ -0,0 +1,20 @@
1
+ const applyJurisdiction = (namespace, jurisdiction) => {
2
+ if (jurisdiction === void 0) {
3
+ return namespace;
4
+ }
5
+ if (typeof namespace.jurisdiction !== "function") {
6
+ throw new TypeError(
7
+ `@lunora/runtime: Durable Object namespace does not support jurisdiction("${jurisdiction}") — update @cloudflare/workers-types or remove the jurisdiction option`
8
+ );
9
+ }
10
+ return namespace.jurisdiction(jurisdiction);
11
+ };
12
+ const resolveShard = (namespace, shardKey) => {
13
+ if (typeof namespace.getByName === "function") {
14
+ return namespace.getByName(shardKey);
15
+ }
16
+ const id = namespace.idFromName(shardKey);
17
+ return namespace.get(id);
18
+ };
19
+
20
+ export { applyJurisdiction, resolveShard };
@@ -1,6 +1,6 @@
1
1
  import { LunoraError, toErrorResponse, isStructuralLunoraError, isStructuralConflictError } from './LunoraError-CL0aOtpo.mjs';
2
2
  import { emitRpcEvent } from './emitLogEvent-pEdtqAK8.mjs';
3
- import { resolveShard } from './resolveShard-DDkzWtrU.mjs';
3
+ import { resolveShard, applyJurisdiction } from './applyJurisdiction-BkZtTkct.mjs';
4
4
  import { resolveSecurity, handleCorsPreflight, enforceOrigin, decorateResponse } from './decorateResponse-DbISh_Wi.mjs';
5
5
 
6
6
  const AUTH_BASE = "/_lunora/admin/auth";
@@ -597,14 +597,14 @@ const partitionExportTables = (options, tables) => {
597
597
  }
598
598
  return { globalTables, shardLocalTables };
599
599
  };
600
- const exportShardLocalRows = async (options, coordinator, forwardedHeaders, tables, shardLocalTables, writeRow) => {
600
+ const exportShardLocalRows = async (options, coordinator, forwardedHeaders, tables, shardLocalTables, writeRow, namespace) => {
601
601
  if (tables !== void 0 && shardLocalTables.length === 0) {
602
602
  return;
603
603
  }
604
604
  const exportTables = tables === void 0 ? [] : shardLocalTables;
605
605
  const probeFallback = tables === void 0 ? collectKnownTables() : [];
606
606
  const probeTables = exportTables.length > 0 ? exportTables : probeFallback;
607
- const result = await coordinator.orchestrateExport(options.shardDO, {
607
+ const result = await coordinator.orchestrateExport(namespace, {
608
608
  args: { tables: exportTables },
609
609
  headers: forwardedHeaders,
610
610
  tables: probeTables
@@ -618,9 +618,9 @@ const exportShardLocalRows = async (options, coordinator, forwardedHeaders, tabl
618
618
  }
619
619
  }
620
620
  };
621
- const streamExportRows = async (options, coordinator, forwardedHeaders, tables, writeRow) => {
621
+ const streamExportRows = async (options, coordinator, forwardedHeaders, tables, writeRow, namespace) => {
622
622
  const { globalTables, shardLocalTables } = partitionExportTables(options, tables);
623
- await exportShardLocalRows(options, coordinator, forwardedHeaders, tables, shardLocalTables, writeRow);
623
+ await exportShardLocalRows(options, coordinator, forwardedHeaders, tables, shardLocalTables, writeRow, namespace);
624
624
  const exportGlobalsFunction = options.exportGlobals;
625
625
  const wantGlobals = tables === void 0 || globalTables.length > 0;
626
626
  if (wantGlobals && exportGlobalsFunction) {
@@ -740,7 +740,7 @@ const mergeImportResult = (totals, result) => {
740
740
  }
741
741
  totals.conflicts += result.conflicts;
742
742
  };
743
- const streamingImport = async (request, options, forwardedHeaders) => {
743
+ const streamingImport = async (request, options, forwardedHeaders, namespace) => {
744
744
  const defaultShard = options.defaultShardKey ?? "__root__";
745
745
  const { errors, globalRows, perShard } = await bucketImportStream(request, options, defaultShard);
746
746
  const totals = { conflicts: 0, errors, inserted: {} };
@@ -749,7 +749,7 @@ const streamingImport = async (request, options, forwardedHeaders) => {
749
749
  if (!coordinator) {
750
750
  throw new LunoraError("Import endpoint requires a `queryCoordinator` on the worker", { code: "BAD_REQUEST", status: 400 });
751
751
  }
752
- const result = await coordinator.orchestrateImport(options.shardDO, {
752
+ const result = await coordinator.orchestrateImport(namespace, {
753
753
  batches: [...perShard.values()],
754
754
  headers: forwardedHeaders
755
755
  });
@@ -1740,6 +1740,8 @@ const checkAdminWsToken = (request, expected) => {
1740
1740
  };
1741
1741
  const createWorker = (options) => {
1742
1742
  const defaultShard = options.defaultShardKey ?? "__root__";
1743
+ const shardDO = applyJurisdiction(options.shardDO, options.jurisdiction);
1744
+ const schedulerDO = options.schedulerDO === void 0 ? void 0 : applyJurisdiction(options.schedulerDO, options.jurisdiction);
1743
1745
  let envAdminToken;
1744
1746
  const effectiveAdminToken = () => options.adminToken ?? envAdminToken;
1745
1747
  const resolveAdminTokenFromEnv = (env) => {
@@ -1772,7 +1774,7 @@ const createWorker = (options) => {
1772
1774
  isAdmin: (request) => checkAdminAuth(request, effectiveAdminToken()),
1773
1775
  queryCoordinator: options.queryCoordinator,
1774
1776
  resolveForwardContext: (request, env) => resolveForwardContext(request, env, options.resolveIdentity),
1775
- shardDO: options.shardDO
1777
+ shardDO
1776
1778
  });
1777
1779
  const dispatchToShard = async (functionPath, args, shardKey) => {
1778
1780
  if (options.authorizeShard) {
@@ -1790,7 +1792,7 @@ const createWorker = (options) => {
1790
1792
  headers: { "content-type": "application/json", "x-lunora-system": "1" },
1791
1793
  method: "POST"
1792
1794
  });
1793
- return forwardToShard(options.shardDO, shardKey, forwarded);
1795
+ return forwardToShard(shardDO, shardKey, forwarded);
1794
1796
  };
1795
1797
  const startCronWorkflow = async (binding, job, env) => {
1796
1798
  const candidate = env?.[binding];
@@ -1858,12 +1860,12 @@ const createWorker = (options) => {
1858
1860
  };
1859
1861
  const releasePoolSlot = async (candidate) => {
1860
1862
  const pool = typeof candidate.pool === "string" && candidate.pool.length > 0 ? candidate.pool : void 0;
1861
- if (!pool || !options.schedulerDO || typeof candidate.id !== "string") {
1863
+ if (!pool || !schedulerDO || typeof candidate.id !== "string") {
1862
1864
  return;
1863
1865
  }
1864
1866
  const instanceName = typeof candidate.instanceName === "string" && candidate.instanceName.length > 0 ? candidate.instanceName : "default";
1865
1867
  try {
1866
- await options.schedulerDO.get(options.schedulerDO.idFromName(instanceName)).fetch(
1868
+ await schedulerDO.get(schedulerDO.idFromName(instanceName)).fetch(
1867
1869
  new Request("https://scheduler.internal/complete", {
1868
1870
  body: JSON.stringify({ id: candidate.id, pool }),
1869
1871
  headers: { "content-type": "application/json" },
@@ -1913,9 +1915,9 @@ const createWorker = (options) => {
1913
1915
  knownTables: () => collectKnownTables(),
1914
1916
  queryCoordinator: options.queryCoordinator,
1915
1917
  resolveForwardContext: (request, env) => resolveForwardContext(request, env, options.resolveIdentity),
1916
- shardDO: options.shardDO,
1917
- streamExportRows: (coordinator, headers, tables, writeRow) => streamExportRows(options, coordinator, headers, tables, writeRow),
1918
- streamingImport: (request, headers) => streamingImport(request, options, headers),
1918
+ shardDO,
1919
+ streamExportRows: (coordinator, headers, tables, writeRow) => streamExportRows(options, coordinator, headers, tables, writeRow, shardDO),
1920
+ streamingImport: (request, headers) => streamingImport(request, options, headers, shardDO),
1919
1921
  syncGlobals: options.syncGlobals
1920
1922
  });
1921
1923
  const assertAdminAuthorized = (request) => {
@@ -1946,10 +1948,10 @@ const createWorker = (options) => {
1946
1948
  };
1947
1949
  };
1948
1950
  const requireSchedulerNamespace = () => {
1949
- if (options.schedulerDO === void 0) {
1951
+ if (schedulerDO === void 0) {
1950
1952
  throw new LunoraError("scheduled endpoints require a `schedulerDO` namespace on the worker", { code: "SCHEDULER_NOT_CONFIGURED", status: 400 });
1951
1953
  }
1952
- return options.schedulerDO;
1954
+ return schedulerDO;
1953
1955
  };
1954
1956
  const resolveSchedulerStub = (request) => {
1955
1957
  assertAdminAuthorized(request);
@@ -2009,7 +2011,7 @@ const createWorker = (options) => {
2009
2011
  headers,
2010
2012
  method: "POST"
2011
2013
  });
2012
- const response = await forwardToShard(options.shardDO, defaultShard, forwarded);
2014
+ const response = await forwardToShard(shardDO, defaultShard, forwarded);
2013
2015
  const payload = await response.json();
2014
2016
  if (payload.error) {
2015
2017
  throw new LunoraError(payload.error.message ?? "shard RPC failed", {
@@ -2072,7 +2074,7 @@ const createWorker = (options) => {
2072
2074
  if (forwardedExp !== void 0) {
2073
2075
  upgradeHeaders.set("x-lunora-identity-exp", forwardedExp);
2074
2076
  }
2075
- return forwardToShard(options.shardDO, shardKey, new Request(request, { headers: upgradeHeaders }));
2077
+ return forwardToShard(shardDO, shardKey, new Request(request, { headers: upgradeHeaders }));
2076
2078
  };
2077
2079
  const authorizeRpcEnvelope = async (envelope, identity) => {
2078
2080
  if (envelope.fanOut) {
@@ -2118,7 +2120,7 @@ const createWorker = (options) => {
2118
2120
  method: "POST"
2119
2121
  });
2120
2122
  try {
2121
- const response = await forwardToShard(options.shardDO, shardKey, forwarded);
2123
+ const response = await forwardToShard(shardDO, shardKey, forwarded);
2122
2124
  emitRpcEvent(
2123
2125
  observability,
2124
2126
  {
@@ -2181,7 +2183,7 @@ const createWorker = (options) => {
2181
2183
  });
2182
2184
  }
2183
2185
  try {
2184
- const result = await coordinator.fanOut(options.shardDO, {
2186
+ const result = await coordinator.fanOut(shardDO, {
2185
2187
  args: envelope.args ?? {},
2186
2188
  fanOut: envelope.fanOut,
2187
2189
  functionPath: envelope.functionPath,
@@ -2290,7 +2292,7 @@ const createWorker = (options) => {
2290
2292
  streamController.enqueue(encoded);
2291
2293
  };
2292
2294
  try {
2293
- await streamExportRows(options, coordinator, forwardedHeaders, tables, writeRow);
2295
+ await streamExportRows(options, coordinator, forwardedHeaders, tables, writeRow, shardDO);
2294
2296
  streamController.close();
2295
2297
  } catch (error) {
2296
2298
  streamError = error instanceof Error ? error : new Error(String(error));
@@ -2359,7 +2361,7 @@ const createWorker = (options) => {
2359
2361
  headers: { authorization: `Bearer ${adminBearer}`, "content-type": "application/json" },
2360
2362
  method: "POST"
2361
2363
  });
2362
- await forwardToShard(options.shardDO, defaultShard, recordRequest);
2364
+ await forwardToShard(shardDO, defaultShard, recordRequest);
2363
2365
  } catch {
2364
2366
  }
2365
2367
  };
@@ -2465,6 +2467,9 @@ const createWorker = (options) => {
2465
2467
  return decorateResponse(toErrorResponse(error), request, resolvedSecurity);
2466
2468
  }
2467
2469
  },
2470
+ async queue(batch, env, context) {
2471
+ await options.queue?.(batch, env, context);
2472
+ },
2468
2473
  async scheduled(controller, env, context) {
2469
2474
  await handleScheduled(controller, env, context);
2470
2475
  },
@@ -2495,6 +2500,7 @@ const withFrameworkWorker = (host, optionsInput) => {
2495
2500
  const optionsFactory = optionsInput;
2496
2501
  return {
2497
2502
  fetch: (request, env, context) => build(optionsFactory(env)).fetch(request, env, context),
2503
+ queue: (batch, env, context) => build(optionsFactory(env)).queue?.(batch, env, context) ?? Promise.resolve(),
2498
2504
  scheduled: (controller, env, context) => build(optionsFactory(env)).scheduled(controller, env, context),
2499
2505
  serverQuery: (request, env, reference, args, options) => build(optionsFactory(env)).serverQuery(request, env, reference, args, options)
2500
2506
  };
@@ -1,5 +1,5 @@
1
1
  import { LunoraError } from './LunoraError-CL0aOtpo.mjs';
2
- import { resolveShard } from './resolveShard-DDkzWtrU.mjs';
2
+ import { resolveShard } from './applyJurisdiction-BkZtTkct.mjs';
3
3
 
4
4
  const createStaticShardRegistry = (table_to_keys) => {
5
5
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/runtime",
3
- "version": "1.0.0-alpha.3",
3
+ "version": "1.0.0-alpha.5",
4
4
  "description": "Lunora Worker runtime: the RPC router, shard resolver, and query coordinator",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -25,7 +25,7 @@
25
25
  "directory": "packages/runtime"
26
26
  },
27
27
  "files": [
28
- "dist",
28
+ "./dist",
29
29
  "README.md",
30
30
  "LICENSE.md",
31
31
  "__assets__"
@@ -1,9 +0,0 @@
1
- const resolveShard = (namespace, shardKey) => {
2
- if (typeof namespace.getByName === "function") {
3
- return namespace.getByName(shardKey);
4
- }
5
- const id = namespace.idFromName(shardKey);
6
- return namespace.get(id);
7
- };
8
-
9
- export { resolveShard };