@lunora/runtime 1.0.0-alpha.2 → 1.0.0-alpha.21
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/LICENSE.md +6 -0
- package/README.md +17 -0
- package/__assets__/package-og.svg +1 -1
- package/dist/index.d.mts +561 -80
- package/dist/index.d.ts +561 -80
- package/dist/index.mjs +9 -7
- package/dist/packem_shared/{DEFAULT_REGISTRY_CACHE_TTL_MS-BpCwo_mo.mjs → DEFAULT_REGISTRY_CACHE_TTL_MS-B3pA7aXp.mjs} +9 -5
- package/dist/packem_shared/LunoraError-Bpb9EFJ3.mjs +22 -0
- package/dist/packem_shared/NOOP_EXECUTION_CONTEXT-CCTu0Bf1.mjs +8 -0
- package/dist/packem_shared/applyJurisdiction-BkZtTkct.mjs +20 -0
- package/dist/packem_shared/composeIdentityResolvers-XGjO7V1J.mjs +55 -0
- package/dist/packem_shared/{composeWorker-BmfKl1ei.mjs → composeWorker-Dpw9d1s5.mjs} +707 -91
- package/dist/packem_shared/{createCrossShardRelationCapabilities-C0KOf7er.mjs → createCrossShardRelationCapabilities-CbcWjkAn.mjs} +4 -2
- package/dist/packem_shared/{createQueryCoordinator-DbxC7iUz.mjs → createQueryCoordinator-DNCJzOZE.mjs} +12 -3
- package/dist/packem_shared/{decorateResponse-DbISh_Wi.mjs → decorateResponse-CsZc49QC.mjs} +42 -9
- package/package.json +5 -2
- package/dist/packem_shared/LunoraError-CL0aOtpo.mjs +0 -46
- package/dist/packem_shared/resolveShard-DDkzWtrU.mjs +0 -9
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { toAirbyteMessages, toFivetranResponse } from './packem_shared/toAirbyteMessages-DrHdplb4.mjs';
|
|
2
|
-
export { composeWorker, createWorker, defineRpcEnvelope, withFrameworkWorker } from './packem_shared/composeWorker-
|
|
3
|
-
export { createCrossShardRelationCapabilities } from './packem_shared/createCrossShardRelationCapabilities-
|
|
4
|
-
export { DEFAULT_REGISTRY_CACHE_TTL_MS, SHARD_REGISTRY_DO_NAME, createDynamicShardRegistry } from './packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-
|
|
5
|
-
export { LunoraError, toErrorResponse } from './packem_shared/LunoraError-
|
|
2
|
+
export { composeWorker, createLunoraHandler, createWorker, defineRpcEnvelope, resolveLunoraOptions, withFrameworkWorker } from './packem_shared/composeWorker-Dpw9d1s5.mjs';
|
|
3
|
+
export { createCrossShardRelationCapabilities } from './packem_shared/createCrossShardRelationCapabilities-CbcWjkAn.mjs';
|
|
4
|
+
export { DEFAULT_REGISTRY_CACHE_TTL_MS, SHARD_REGISTRY_DO_NAME, createDynamicShardRegistry } from './packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-B3pA7aXp.mjs';
|
|
5
|
+
export { LunoraError, toErrorResponse } from './packem_shared/LunoraError-Bpb9EFJ3.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-
|
|
9
|
-
export { resolveShard } from './packem_shared/
|
|
10
|
-
export { decorateResponse, enforceOrigin, handleCorsPreflight, resolveSecurity } from './packem_shared/decorateResponse-
|
|
8
|
+
export { createQueryCoordinator, createStaticShardRegistry, mergeStrategyForAggregate } from './packem_shared/createQueryCoordinator-DNCJzOZE.mjs';
|
|
9
|
+
export { applyJurisdiction, resolveShard } from './packem_shared/applyJurisdiction-BkZtTkct.mjs';
|
|
10
|
+
export { decorateResponse, enforceOrigin, handleCorsPreflight, resolveSecurity } from './packem_shared/decorateResponse-CsZc49QC.mjs';
|
|
11
|
+
export { NOOP_EXECUTION_CONTEXT } from './packem_shared/NOOP_EXECUTION_CONTEXT-CCTu0Bf1.mjs';
|
|
12
|
+
export { composeIdentityResolvers, routeIdentityResolvers } from './packem_shared/composeIdentityResolvers-XGjO7V1J.mjs';
|
|
11
13
|
|
|
12
14
|
const VERSION = "0.0.0";
|
|
13
15
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { LunoraError } from './LunoraError-Bpb9EFJ3.mjs';
|
|
2
|
+
import { applyJurisdiction } from './applyJurisdiction-BkZtTkct.mjs';
|
|
3
|
+
|
|
1
4
|
const SHARD_REGISTRY_DO_NAME = "__lunora_shard_registry__";
|
|
2
5
|
const DEFAULT_REGISTRY_CACHE_TTL_MS = 3e4;
|
|
3
6
|
const REGISTRY_BASE_URL = "https://shard-registry.internal";
|
|
@@ -10,9 +13,10 @@ const createDynamicShardRegistry = (options) => {
|
|
|
10
13
|
const instanceName = options.instanceName ?? SHARD_REGISTRY_DO_NAME;
|
|
11
14
|
const cacheTtlMs = options.cacheTtlMs ?? DEFAULT_REGISTRY_CACHE_TTL_MS;
|
|
12
15
|
const cache = /* @__PURE__ */ new Map();
|
|
16
|
+
const namespace = applyJurisdiction(options.namespace, options.jurisdiction);
|
|
13
17
|
let cachedStub;
|
|
14
18
|
const stub = () => {
|
|
15
|
-
cachedStub ??=
|
|
19
|
+
cachedStub ??= namespace.get(namespace.idFromName(instanceName));
|
|
16
20
|
return cachedStub;
|
|
17
21
|
};
|
|
18
22
|
const post = async (path, body) => stub().fetch(
|
|
@@ -39,7 +43,7 @@ const createDynamicShardRegistry = (options) => {
|
|
|
39
43
|
}
|
|
40
44
|
const response = await get(`/list?table=${encodeURIComponent(table)}`);
|
|
41
45
|
if (!response.ok) {
|
|
42
|
-
throw new
|
|
46
|
+
throw new LunoraError(`shard registry /list returned ${String(response.status)}`);
|
|
43
47
|
}
|
|
44
48
|
const { shardKeys } = await decodeJson(response);
|
|
45
49
|
if (cacheTtlMs > 0) {
|
|
@@ -50,14 +54,14 @@ const createDynamicShardRegistry = (options) => {
|
|
|
50
54
|
async register(table, shardKey) {
|
|
51
55
|
const response = await post("/register", { shardKey, table });
|
|
52
56
|
if (!response.ok) {
|
|
53
|
-
throw new
|
|
57
|
+
throw new LunoraError(`shard registry /register returned ${String(response.status)}`);
|
|
54
58
|
}
|
|
55
59
|
cache.delete(table);
|
|
56
60
|
},
|
|
57
61
|
async snapshot() {
|
|
58
62
|
const response = await get("/snapshot");
|
|
59
63
|
if (!response.ok) {
|
|
60
|
-
throw new
|
|
64
|
+
throw new LunoraError(`shard registry /snapshot returned ${String(response.status)}`);
|
|
61
65
|
}
|
|
62
66
|
const { tables } = await decodeJson(response);
|
|
63
67
|
return tables;
|
|
@@ -65,7 +69,7 @@ const createDynamicShardRegistry = (options) => {
|
|
|
65
69
|
async unregister(table, shardKey) {
|
|
66
70
|
const response = await post("/unregister", { shardKey, table });
|
|
67
71
|
if (!response.ok) {
|
|
68
|
-
throw new
|
|
72
|
+
throw new LunoraError(`shard registry /unregister returned ${String(response.status)}`);
|
|
69
73
|
}
|
|
70
74
|
cache.delete(table);
|
|
71
75
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1, toErrorBody } from '@lunora/errors';
|
|
2
|
+
|
|
3
|
+
const toErrorResponse = (error) => {
|
|
4
|
+
const { body, redacted, status } = toErrorBody(error, { fallbackCode: "INTERNAL", redactedMessage: "Internal error" });
|
|
5
|
+
if (redacted) {
|
|
6
|
+
console.error("[lunora] internal error:", error);
|
|
7
|
+
}
|
|
8
|
+
return Response.json({ error: body }, {
|
|
9
|
+
headers: { "content-type": "application/json" },
|
|
10
|
+
status
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
class LunoraError extends LunoraError$1 {
|
|
14
|
+
constructor(message, options) {
|
|
15
|
+
super(options?.code ?? "INTERNAL", message, { cause: options?.cause, status: options?.status });
|
|
16
|
+
}
|
|
17
|
+
toResponse() {
|
|
18
|
+
return toErrorResponse(this);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { LunoraError, toErrorResponse };
|
|
@@ -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 };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { LunoraError } from './LunoraError-Bpb9EFJ3.mjs';
|
|
2
|
+
|
|
3
|
+
const composeIdentityResolvers = (resolvers, options = {}) => {
|
|
4
|
+
const onError = options.onError ?? "fail-closed";
|
|
5
|
+
return async (request, env) => {
|
|
6
|
+
for (const resolver of resolvers) {
|
|
7
|
+
let resolved;
|
|
8
|
+
try {
|
|
9
|
+
resolved = await resolver(request, env);
|
|
10
|
+
} catch (error) {
|
|
11
|
+
if (onError === "skip") {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
if (resolved) {
|
|
17
|
+
return resolved;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
const routeIdentityResolvers = (routes) => {
|
|
24
|
+
const prefixes = Object.keys(routes).filter((key) => key !== "*").toSorted((a, b) => b.length - a.length);
|
|
25
|
+
return (request, env) => {
|
|
26
|
+
const { pathname } = new URL(request.url);
|
|
27
|
+
const matched = prefixes.find((prefix) => pathname === prefix || pathname.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`));
|
|
28
|
+
const resolver = matched === void 0 ? routes["*"] : routes[matched];
|
|
29
|
+
if (resolver === void 0) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return resolver(request, env);
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const wrapResolverWithContract = (baseResolveIdentity, contract) => {
|
|
36
|
+
if (contract === void 0 || baseResolveIdentity === void 0) {
|
|
37
|
+
return baseResolveIdentity;
|
|
38
|
+
}
|
|
39
|
+
return async (request, env) => {
|
|
40
|
+
const resolved = await baseResolveIdentity(request, env);
|
|
41
|
+
if (!resolved) {
|
|
42
|
+
return resolved;
|
|
43
|
+
}
|
|
44
|
+
const result = contract.validate(resolved);
|
|
45
|
+
if (result.ok) {
|
|
46
|
+
return resolved;
|
|
47
|
+
}
|
|
48
|
+
if (contract.onInvalid === "reject") {
|
|
49
|
+
throw new LunoraError(`identity claims failed the declared contract: ${result.error}`, { code: "UNAUTHENTICATED", status: 401 });
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { composeIdentityResolvers, routeIdentityResolvers, wrapResolverWithContract };
|