@lunora/do 1.0.0-alpha.23 → 1.0.0-alpha.25
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/dist/index.d.mts +40 -80
- package/dist/index.d.ts +40 -80
- package/dist/index.mjs +10 -10
- package/dist/packem_shared/{ADMIN_FUNCTIONS-BbQdj8h1.mjs → ADMIN_FUNCTIONS-Bxdijn66.mjs} +7 -5
- package/dist/packem_shared/{MAX_SQL_ROWS-dDcFE1YZ.mjs → MAX_SQL_ROWS-D57CJaT9.mjs} +3 -1
- package/dist/packem_shared/{NotUniqueError-D1U5SBFR.mjs → NotUniqueError-Dmf-HNdQ.mjs} +60 -7
- package/dist/packem_shared/{RLS_UNWRAP_SYMBOL-DnjkqVgY.mjs → RLS_UNWRAP_SYMBOL-G1eNK4DQ.mjs} +8 -0
- package/dist/packem_shared/{ROOT_DO_SIZE_WARN_BYTES-BM4TOOvf.mjs → ROOT_DO_SIZE_WARN_BYTES-CpURtawE.mjs} +79 -133
- package/dist/packem_shared/{SESSION_DO_TTL_DEFAULT-ilPZsVwu.mjs → SESSION_DO_TTL_DEFAULT-D71QAL5h.mjs} +15 -17
- package/dist/packem_shared/{SHARD_REGISTRY_DO_NAME-BsAbi5Mn.mjs → SHARD_REGISTRY_DO_NAME-D99roc-r.mjs} +12 -14
- package/dist/packem_shared/{armRestore-BJk53Ro8.mjs → armRestore-4Px61hHS.mjs} +4 -10
- package/dist/packem_shared/{exportShardRows-DZEhUeyI.mjs → exportShardRows-Dy3oFZ26.mjs} +4 -3
- package/dist/packem_shared/json-response-BdbtpOhm.mjs +3 -0
- package/dist/packem_shared/{serveRelationFanout-BhZF9AuB.mjs → serveRelationFanout-C56hKu1O.mjs} +4 -7
- package/package.json +2 -2
|
@@ -1,22 +1,20 @@
|
|
|
1
|
+
import { j as jsonResponse } from './json-response-BdbtpOhm.mjs';
|
|
2
|
+
|
|
1
3
|
const SHARD_REGISTRY_DO_NAME = "__lunora_shard_registry__";
|
|
2
4
|
const STORAGE_KEY = "__tables__";
|
|
3
|
-
const jsonResponse = (status, body) => Response.json(body, {
|
|
4
|
-
headers: { "content-type": "application/json" },
|
|
5
|
-
status
|
|
6
|
-
});
|
|
7
5
|
const readTableShardBody = async (request) => {
|
|
8
6
|
let body;
|
|
9
7
|
try {
|
|
10
8
|
body = await request.json();
|
|
11
9
|
} catch {
|
|
12
|
-
return { kind: "error", response: jsonResponse(
|
|
10
|
+
return { kind: "error", response: jsonResponse({ error: { code: "BAD_REQUEST", message: "invalid JSON body" } }, 400) };
|
|
13
11
|
}
|
|
14
12
|
const table = typeof body.table === "string" ? body.table.trim() : "";
|
|
15
13
|
const shardKey = typeof body.shardKey === "string" ? body.shardKey.trim() : "";
|
|
16
14
|
if (!table || !shardKey) {
|
|
17
15
|
return {
|
|
18
16
|
kind: "error",
|
|
19
|
-
response: jsonResponse(
|
|
17
|
+
response: jsonResponse({ error: { code: "BAD_REQUEST", message: "table and shardKey required" } }, 400)
|
|
20
18
|
};
|
|
21
19
|
}
|
|
22
20
|
return { kind: "ok", value: { shardKey, table } };
|
|
@@ -56,7 +54,7 @@ class ShardRegistryDO {
|
|
|
56
54
|
if (request.method === "GET" && url.pathname === "/snapshot") {
|
|
57
55
|
return this.handleSnapshot();
|
|
58
56
|
}
|
|
59
|
-
return jsonResponse(
|
|
57
|
+
return jsonResponse({ error: { code: "NOT_FOUND", message: `unknown shard-registry route ${request.method} ${url.pathname}` } }, 404);
|
|
60
58
|
}
|
|
61
59
|
/**
|
|
62
60
|
* Load the persisted snapshot exactly once. `blockConcurrencyWhile`
|
|
@@ -83,9 +81,9 @@ class ShardRegistryDO {
|
|
|
83
81
|
handleList(url) {
|
|
84
82
|
const table = url.searchParams.get("table");
|
|
85
83
|
if (!table) {
|
|
86
|
-
return jsonResponse(
|
|
84
|
+
return jsonResponse({ error: { code: "BAD_REQUEST", message: "missing required query parameter: table" } }, 400);
|
|
87
85
|
}
|
|
88
|
-
return jsonResponse(
|
|
86
|
+
return jsonResponse({ shardKeys: [...this.tables.get(table) ?? []] }, 200);
|
|
89
87
|
}
|
|
90
88
|
async handleRegister(request) {
|
|
91
89
|
const parsed = await readTableShardBody(request);
|
|
@@ -100,11 +98,11 @@ class ShardRegistryDO {
|
|
|
100
98
|
this.tables.set(table, set);
|
|
101
99
|
}
|
|
102
100
|
if (set.has(shardKey)) {
|
|
103
|
-
return jsonResponse(
|
|
101
|
+
return jsonResponse({ changed: false, ok: true }, 200);
|
|
104
102
|
}
|
|
105
103
|
set.add(shardKey);
|
|
106
104
|
await this.persist();
|
|
107
|
-
return jsonResponse(
|
|
105
|
+
return jsonResponse({ changed: true, ok: true }, 200);
|
|
108
106
|
});
|
|
109
107
|
}
|
|
110
108
|
handleSnapshot() {
|
|
@@ -112,7 +110,7 @@ class ShardRegistryDO {
|
|
|
112
110
|
for (const [table, set] of this.tables) {
|
|
113
111
|
out[table] = [...set];
|
|
114
112
|
}
|
|
115
|
-
return jsonResponse(
|
|
113
|
+
return jsonResponse({ tables: out }, 200);
|
|
116
114
|
}
|
|
117
115
|
async handleUnregister(request) {
|
|
118
116
|
const parsed = await readTableShardBody(request);
|
|
@@ -123,14 +121,14 @@ class ShardRegistryDO {
|
|
|
123
121
|
return this.state.blockConcurrencyWhile(async () => {
|
|
124
122
|
const set = this.tables.get(table);
|
|
125
123
|
if (!set?.has(shardKey)) {
|
|
126
|
-
return jsonResponse(
|
|
124
|
+
return jsonResponse({ changed: false, ok: true }, 200);
|
|
127
125
|
}
|
|
128
126
|
set.delete(shardKey);
|
|
129
127
|
if (set.size === 0) {
|
|
130
128
|
this.tables.delete(table);
|
|
131
129
|
}
|
|
132
130
|
await this.persist();
|
|
133
|
-
return jsonResponse(
|
|
131
|
+
return jsonResponse({ changed: true, ok: true }, 200);
|
|
134
132
|
});
|
|
135
133
|
}
|
|
136
134
|
/** Serialize the in-memory map to a single JSON-safe object and put. */
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const pitrUnavailable = () => Object.assign(
|
|
2
4
|
new Error("native PITR is unavailable here (local dev or a non-SQLite Durable Object); use `lunora backup restore` for off-platform recovery"),
|
|
3
5
|
{
|
|
@@ -12,11 +14,7 @@ const toTime = (time) => {
|
|
|
12
14
|
}
|
|
13
15
|
const parsed = Date.parse(time);
|
|
14
16
|
if (Number.isNaN(parsed)) {
|
|
15
|
-
throw
|
|
16
|
-
code: "BAD_REQUEST",
|
|
17
|
-
name: "LunoraError",
|
|
18
|
-
status: 400
|
|
19
|
-
});
|
|
17
|
+
throw new LunoraError("BAD_REQUEST", `pitr: invalid time "${time}" — expected epoch-ms or an ISO timestamp`);
|
|
20
18
|
}
|
|
21
19
|
return parsed;
|
|
22
20
|
};
|
|
@@ -37,11 +35,7 @@ const armRestore = async (storage, args) => {
|
|
|
37
35
|
let target = args.bookmark;
|
|
38
36
|
if (target === void 0) {
|
|
39
37
|
if (args.time === void 0) {
|
|
40
|
-
throw
|
|
41
|
-
code: "BAD_REQUEST",
|
|
42
|
-
name: "LunoraError",
|
|
43
|
-
status: 400
|
|
44
|
-
});
|
|
38
|
+
throw new LunoraError("BAD_REQUEST", "pitrRestore: provide a `bookmark` or a `time` to restore to");
|
|
45
39
|
}
|
|
46
40
|
if (!storage.getBookmarkForTime) {
|
|
47
41
|
throw pitrUnavailable();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { toErrorBody } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const DEFAULT_BATCH_SIZE = 200;
|
|
2
4
|
const selectExportTables = (schema, requested) => {
|
|
3
5
|
const isShardLocal = (table) => {
|
|
@@ -107,9 +109,8 @@ const importOneRow = async (writer, schema, row, line) => {
|
|
|
107
109
|
await writer.insert(table, doc, { allowExplicitId: true });
|
|
108
110
|
return { kind: "inserted", table };
|
|
109
111
|
} catch (error) {
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
return { error: { code, line, message, table }, kind: "error" };
|
|
112
|
+
const { body } = toErrorBody(error, { fallbackCode: "INSERT_FAILED" });
|
|
113
|
+
return { error: { code: body.code, line, message: body.message, table }, kind: "error" };
|
|
113
114
|
}
|
|
114
115
|
};
|
|
115
116
|
const importShardRows = async (writer, schema, args) => {
|
package/dist/packem_shared/{serveRelationFanout-BhZF9AuB.mjs → serveRelationFanout-C56hKu1O.mjs}
RENAMED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LunoraError } from '@lunora/errors';
|
|
2
|
+
import { RELATION_FUNCTION_PREFIX } from './ADMIN_FUNCTIONS-Bxdijn66.mjs';
|
|
2
3
|
|
|
3
4
|
const serveRelationFanout = async (schema, database, functionPath, args) => {
|
|
4
5
|
const table = typeof args["table"] === "string" ? args["table"] : "";
|
|
5
6
|
const definition = schema.tables[table];
|
|
6
7
|
if (!definition) {
|
|
7
|
-
throw
|
|
8
|
+
throw new LunoraError("UNKNOWN_TABLE", `${RELATION_FUNCTION_PREFIX} unknown table "${table}"`, { status: 404 });
|
|
8
9
|
}
|
|
9
10
|
if (definition.shardMode?.kind === "global") {
|
|
10
|
-
throw
|
|
11
|
-
code: "BAD_REQUEST",
|
|
12
|
-
name: "LunoraError",
|
|
13
|
-
status: 400
|
|
14
|
-
});
|
|
11
|
+
throw new LunoraError("BAD_REQUEST", `${RELATION_FUNCTION_PREFIX} table "${table}" is global, not shard-local`);
|
|
15
12
|
}
|
|
16
13
|
const where = args["where"] ?? void 0;
|
|
17
14
|
if (functionPath === `${RELATION_FUNCTION_PREFIX}count`) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/do",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.25",
|
|
4
4
|
"description": "Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
49
|
+
"@lunora/errors": "1.0.0-alpha.2",
|
|
50
50
|
"@visulima/redact": "3.0.0-alpha.14",
|
|
51
51
|
"drizzle-orm": "^0.45.2"
|
|
52
52
|
},
|