@mionjs/client 0.8.10 → 0.13.2
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/cjs/index.cjs +1 -2
- package/.dist/cjs/index.d.ts +5 -2
- package/.dist/cjs/middlewares.cjs +1 -0
- package/.dist/cjs/middlewares.d.ts +3 -0
- package/.dist/cjs/src/batch.cjs +3 -0
- package/.dist/cjs/src/batch.cjs.map +1 -0
- package/.dist/cjs/src/batch.d.ts +7 -0
- package/.dist/cjs/src/callContext.cjs +3 -0
- package/.dist/cjs/src/callContext.cjs.map +1 -0
- package/.dist/cjs/src/callContext.d.ts +6 -0
- package/.dist/cjs/src/client.cjs +3 -2
- package/.dist/cjs/src/client.cjs.map +1 -1
- package/.dist/cjs/src/client.d.ts +8 -13
- package/.dist/cjs/src/constants.cjs +3 -2
- package/.dist/cjs/src/constants.cjs.map +1 -1
- package/.dist/cjs/src/constants.d.ts +7 -3
- package/.dist/cjs/src/dispatch.cjs +3 -0
- package/.dist/cjs/src/dispatch.cjs.map +1 -0
- package/.dist/cjs/src/dispatch.d.ts +8 -0
- package/.dist/cjs/src/lib/apiBuildVersion.cjs +3 -0
- package/.dist/cjs/src/lib/apiBuildVersion.cjs.map +1 -0
- package/.dist/cjs/src/lib/apiBuildVersion.d.ts +10 -0
- package/.dist/cjs/src/lib/apiVersionRecovery.cjs +3 -0
- package/.dist/cjs/src/lib/apiVersionRecovery.cjs.map +1 -0
- package/.dist/cjs/src/lib/apiVersionRecovery.d.ts +7 -0
- package/.dist/cjs/src/lib/bundledApi.cjs +3 -0
- package/.dist/cjs/src/lib/bundledApi.cjs.map +1 -0
- package/.dist/cjs/src/lib/bundledApi.d.ts +12 -0
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs +3 -2
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs.map +1 -1
- package/.dist/cjs/src/lib/clientMethodsMetadata.d.ts +10 -10
- package/.dist/cjs/src/lib/clientResponse.cjs +3 -0
- package/.dist/cjs/src/lib/clientResponse.cjs.map +1 -0
- package/.dist/cjs/src/lib/clientResponse.d.ts +9 -0
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.cjs +3 -2
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.cjs.map +1 -1
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.d.ts +1 -1
- package/.dist/cjs/src/lib/handlersRegistry.cjs +3 -2
- package/.dist/cjs/src/lib/handlersRegistry.cjs.map +1 -1
- package/.dist/cjs/src/lib/handlersRegistry.d.ts +18 -9
- package/.dist/cjs/src/lib/headers.cjs +3 -0
- package/.dist/cjs/src/lib/headers.cjs.map +1 -0
- package/.dist/cjs/src/lib/headers.d.ts +7 -0
- package/.dist/cjs/src/lib/metadataEviction.cjs +3 -0
- package/.dist/cjs/src/lib/metadataEviction.cjs.map +1 -0
- package/.dist/cjs/src/lib/metadataEviction.d.ts +9 -0
- package/.dist/cjs/src/lib/metadataFetcher.cjs +3 -0
- package/.dist/cjs/src/lib/metadataFetcher.cjs.map +1 -0
- package/.dist/cjs/src/lib/metadataFetcher.d.ts +29 -0
- package/.dist/cjs/src/lib/metadataFromServer.cjs +1 -0
- package/.dist/cjs/src/lib/metadataFromServer.d.ts +4 -0
- package/.dist/cjs/src/lib/metadataFromServerLoader.cjs +3 -0
- package/.dist/cjs/src/lib/metadataFromServerLoader.cjs.map +1 -0
- package/.dist/cjs/src/lib/metadataFromServerLoader.d.ts +6 -0
- package/.dist/cjs/src/lib/metadataStore.cjs +3 -0
- package/.dist/cjs/src/lib/metadataStore.cjs.map +1 -0
- package/.dist/cjs/src/lib/metadataStore.d.ts +23 -0
- package/.dist/cjs/src/lib/methods.cjs +3 -0
- package/.dist/cjs/src/lib/methods.cjs.map +1 -0
- package/.dist/cjs/src/lib/methods.d.ts +15 -0
- package/.dist/cjs/src/lib/persistentStorage.cjs +3 -0
- package/.dist/cjs/src/lib/persistentStorage.cjs.map +1 -0
- package/.dist/cjs/src/lib/persistentStorage.d.ts +3 -0
- package/.dist/cjs/src/lib/sanitize.cjs +3 -0
- package/.dist/cjs/src/lib/sanitize.cjs.map +1 -0
- package/.dist/cjs/src/lib/sanitize.d.ts +3 -0
- package/.dist/cjs/src/lib/serializer.cjs +3 -2
- package/.dist/cjs/src/lib/serializer.cjs.map +1 -1
- package/.dist/cjs/src/lib/serializer.d.ts +8 -6
- package/.dist/cjs/src/lib/storage.cjs +0 -2
- package/.dist/cjs/src/lib/storage.d.ts +17 -10
- package/.dist/cjs/src/lib/typedEvent.cjs +3 -2
- package/.dist/cjs/src/lib/typedEvent.cjs.map +1 -1
- package/.dist/cjs/src/lib/typedEvent.d.ts +12 -10
- package/.dist/cjs/src/lib/validation.cjs +3 -2
- package/.dist/cjs/src/lib/validation.cjs.map +1 -1
- package/.dist/cjs/src/lib/validation.d.ts +4 -3
- package/.dist/cjs/src/middlewares/fetchMetadata.cjs +3 -0
- package/.dist/cjs/src/middlewares/fetchMetadata.cjs.map +1 -0
- package/.dist/cjs/src/middlewares/fetchMetadata.d.ts +4 -0
- package/.dist/cjs/src/middlewares/syncRoutes.cjs +3 -0
- package/.dist/cjs/src/middlewares/syncRoutes.cjs.map +1 -0
- package/.dist/cjs/src/middlewares/syncRoutes.d.ts +4 -0
- package/.dist/cjs/src/subRequest.cjs +3 -2
- package/.dist/cjs/src/subRequest.cjs.map +1 -1
- package/.dist/cjs/src/subRequest.d.ts +6 -10
- package/.dist/cjs/src/types.cjs +0 -2
- package/.dist/cjs/src/types.d.ts +91 -80
- package/.dist/esm/index.d.ts +5 -2
- package/.dist/esm/index.js +47 -28
- package/.dist/esm/middlewares.d.ts +3 -0
- package/.dist/esm/middlewares.js +6 -0
- package/.dist/esm/src/batch.d.ts +7 -0
- package/.dist/esm/src/batch.js +50 -0
- package/.dist/esm/src/batch.js.map +1 -0
- package/.dist/esm/src/callContext.d.ts +6 -0
- package/.dist/esm/src/callContext.js +34 -0
- package/.dist/esm/src/callContext.js.map +1 -0
- package/.dist/esm/src/client.d.ts +8 -13
- package/.dist/esm/src/client.js +54 -108
- package/.dist/esm/src/client.js.map +1 -1
- package/.dist/esm/src/constants.d.ts +7 -3
- package/.dist/esm/src/constants.js +21 -17
- package/.dist/esm/src/constants.js.map +1 -1
- package/.dist/esm/src/dispatch.d.ts +8 -0
- package/.dist/esm/src/dispatch.js +390 -0
- package/.dist/esm/src/dispatch.js.map +1 -0
- package/.dist/esm/src/lib/apiBuildVersion.d.ts +10 -0
- package/.dist/esm/src/lib/apiBuildVersion.js +43 -0
- package/.dist/esm/src/lib/apiBuildVersion.js.map +1 -0
- package/.dist/esm/src/lib/apiVersionRecovery.d.ts +7 -0
- package/.dist/esm/src/lib/apiVersionRecovery.js +43 -0
- package/.dist/esm/src/lib/apiVersionRecovery.js.map +1 -0
- package/.dist/esm/src/lib/bundledApi.d.ts +12 -0
- package/.dist/esm/src/lib/bundledApi.js +52 -0
- package/.dist/esm/src/lib/bundledApi.js.map +1 -0
- package/.dist/esm/src/lib/clientMethodsMetadata.d.ts +10 -10
- package/.dist/esm/src/lib/clientMethodsMetadata.js +257 -101
- package/.dist/esm/src/lib/clientMethodsMetadata.js.map +1 -1
- package/.dist/esm/src/lib/clientResponse.d.ts +9 -0
- package/.dist/esm/src/lib/clientResponse.js +53 -0
- package/.dist/esm/src/lib/clientResponse.js.map +1 -0
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.d.ts +1 -1
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.js +20 -17
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.js.map +1 -1
- package/.dist/esm/src/lib/handlersRegistry.d.ts +18 -9
- package/.dist/esm/src/lib/handlersRegistry.js +53 -38
- package/.dist/esm/src/lib/handlersRegistry.js.map +1 -1
- package/.dist/esm/src/lib/headers.d.ts +7 -0
- package/.dist/esm/src/lib/headers.js +47 -0
- package/.dist/esm/src/lib/headers.js.map +1 -0
- package/.dist/esm/src/lib/metadataEviction.d.ts +9 -0
- package/.dist/esm/src/lib/metadataEviction.js +33 -0
- package/.dist/esm/src/lib/metadataEviction.js.map +1 -0
- package/.dist/esm/src/lib/metadataFetcher.d.ts +29 -0
- package/.dist/esm/src/lib/metadataFetcher.js +24 -0
- package/.dist/esm/src/lib/metadataFetcher.js.map +1 -0
- package/.dist/esm/src/lib/metadataFromServer.d.ts +4 -0
- package/.dist/esm/src/lib/metadataFromServer.js +15 -0
- package/.dist/esm/src/lib/metadataFromServerLoader.d.ts +6 -0
- package/.dist/esm/src/lib/metadataFromServerLoader.js +27 -0
- package/.dist/esm/src/lib/metadataFromServerLoader.js.map +1 -0
- package/.dist/esm/src/lib/metadataStore.d.ts +23 -0
- package/.dist/esm/src/lib/metadataStore.js +152 -0
- package/.dist/esm/src/lib/metadataStore.js.map +1 -0
- package/.dist/esm/src/lib/methods.d.ts +15 -0
- package/.dist/esm/src/lib/methods.js +41 -0
- package/.dist/esm/src/lib/methods.js.map +1 -0
- package/.dist/esm/src/lib/persistentStorage.d.ts +3 -0
- package/.dist/esm/src/lib/persistentStorage.js +26 -0
- package/.dist/esm/src/lib/persistentStorage.js.map +1 -0
- package/.dist/esm/src/lib/sanitize.d.ts +3 -0
- package/.dist/esm/src/lib/sanitize.js +25 -0
- package/.dist/esm/src/lib/sanitize.js.map +1 -0
- package/.dist/esm/src/lib/serializer.d.ts +8 -6
- package/.dist/esm/src/lib/serializer.js +75 -110
- package/.dist/esm/src/lib/serializer.js.map +1 -1
- package/.dist/esm/src/lib/storage.d.ts +17 -10
- package/.dist/esm/src/lib/storage.js +0 -43
- package/.dist/esm/src/lib/typedEvent.d.ts +12 -10
- package/.dist/esm/src/lib/typedEvent.js +25 -20
- package/.dist/esm/src/lib/typedEvent.js.map +1 -1
- package/.dist/esm/src/lib/validation.d.ts +4 -3
- package/.dist/esm/src/lib/validation.js +38 -33
- package/.dist/esm/src/lib/validation.js.map +1 -1
- package/.dist/esm/src/middlewares/fetchMetadata.d.ts +4 -0
- package/.dist/esm/src/middlewares/fetchMetadata.js +85 -0
- package/.dist/esm/src/middlewares/fetchMetadata.js.map +1 -0
- package/.dist/esm/src/middlewares/syncRoutes.d.ts +4 -0
- package/.dist/esm/src/middlewares/syncRoutes.js +20 -0
- package/.dist/esm/src/middlewares/syncRoutes.js.map +1 -0
- package/.dist/esm/src/subRequest.d.ts +6 -10
- package/.dist/esm/src/subRequest.js +11 -32
- package/.dist/esm/src/subRequest.js.map +1 -1
- package/.dist/esm/src/types.d.ts +91 -80
- package/.dist/esm/src/types.js +0 -2
- package/LICENSE +1 -1
- package/README.md +6 -6
- package/package.json +38 -26
- package/.dist/cjs/index.cjs.map +0 -1
- package/.dist/cjs/index.d.ts.map +0 -1
- package/.dist/cjs/src/client.d.ts.map +0 -1
- package/.dist/cjs/src/constants.d.ts.map +0 -1
- package/.dist/cjs/src/lib/clientMethodsMetadata.d.ts.map +0 -1
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.d.ts.map +0 -1
- package/.dist/cjs/src/lib/handlersRegistry.d.ts.map +0 -1
- package/.dist/cjs/src/lib/serializer.d.ts.map +0 -1
- package/.dist/cjs/src/lib/storage.cjs.map +0 -1
- package/.dist/cjs/src/lib/storage.d.ts.map +0 -1
- package/.dist/cjs/src/lib/testUtils.cjs +0 -2
- package/.dist/cjs/src/lib/testUtils.cjs.map +0 -1
- package/.dist/cjs/src/lib/testUtils.d.ts +0 -2
- package/.dist/cjs/src/lib/testUtils.d.ts.map +0 -1
- package/.dist/cjs/src/lib/typedEvent.d.ts.map +0 -1
- package/.dist/cjs/src/lib/validation.d.ts.map +0 -1
- package/.dist/cjs/src/request.cjs +0 -2
- package/.dist/cjs/src/request.cjs.map +0 -1
- package/.dist/cjs/src/request.d.ts +0 -37
- package/.dist/cjs/src/request.d.ts.map +0 -1
- package/.dist/cjs/src/routesFlow.cjs +0 -2
- package/.dist/cjs/src/routesFlow.cjs.map +0 -1
- package/.dist/cjs/src/routesFlow.d.ts +0 -7
- package/.dist/cjs/src/routesFlow.d.ts.map +0 -1
- package/.dist/cjs/src/subRequest.d.ts.map +0 -1
- package/.dist/cjs/src/types.cjs.map +0 -1
- package/.dist/cjs/src/types.d.ts.map +0 -1
- package/.dist/esm/index.d.ts.map +0 -1
- package/.dist/esm/index.js.map +0 -1
- package/.dist/esm/src/client.d.ts.map +0 -1
- package/.dist/esm/src/constants.d.ts.map +0 -1
- package/.dist/esm/src/lib/clientMethodsMetadata.d.ts.map +0 -1
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.d.ts.map +0 -1
- package/.dist/esm/src/lib/handlersRegistry.d.ts.map +0 -1
- package/.dist/esm/src/lib/serializer.d.ts.map +0 -1
- package/.dist/esm/src/lib/storage.d.ts.map +0 -1
- package/.dist/esm/src/lib/storage.js.map +0 -1
- package/.dist/esm/src/lib/testUtils.d.ts +0 -2
- package/.dist/esm/src/lib/testUtils.d.ts.map +0 -1
- package/.dist/esm/src/lib/testUtils.js +0 -11
- package/.dist/esm/src/lib/testUtils.js.map +0 -1
- package/.dist/esm/src/lib/typedEvent.d.ts.map +0 -1
- package/.dist/esm/src/lib/validation.d.ts.map +0 -1
- package/.dist/esm/src/request.d.ts +0 -37
- package/.dist/esm/src/request.d.ts.map +0 -1
- package/.dist/esm/src/request.js +0 -334
- package/.dist/esm/src/request.js.map +0 -1
- package/.dist/esm/src/routesFlow.d.ts +0 -7
- package/.dist/esm/src/routesFlow.d.ts.map +0 -1
- package/.dist/esm/src/routesFlow.js +0 -60
- package/.dist/esm/src/routesFlow.js.map +0 -1
- package/.dist/esm/src/subRequest.d.ts.map +0 -1
- package/.dist/esm/src/types.d.ts.map +0 -1
- package/.dist/esm/src/types.js.map +0 -1
- package/index.ts +0 -19
- package/src/client.ts +0 -290
- package/src/constants.ts +0 -37
- package/src/lib/clientMethodsMetadata.ts +0 -187
- package/src/lib/fetchRemoteMethodsMetadata.ts +0 -44
- package/src/lib/handlersRegistry.ts +0 -101
- package/src/lib/serializer.ts +0 -245
- package/src/lib/storage.ts +0 -57
- package/src/lib/testUtils.ts +0 -16
- package/src/lib/typedEvent.ts +0 -57
- package/src/lib/validation.ts +0 -72
- package/src/request.ts +0 -563
- package/src/routesFlow.ts +0 -101
- package/src/subRequest.ts +0 -111
- package/src/types.ts +0 -237
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { DEFAULT_STORAGE_ENGINE, STORAGE_KEY } from "../constants.js";
|
|
2
|
+
var STORE_GLOBAL_KEY = "__mion_metadata_store__", OBJECT_STORE = "metadata", DB_VERSION = 1, OPEN_TIMEOUT_MS = 3e3, MemoryMetadataStore = class {
|
|
3
|
+
kind = "memory";
|
|
4
|
+
records = /* @__PURE__ */ new Map();
|
|
5
|
+
async readAll(baseURL) {
|
|
6
|
+
const result = [];
|
|
7
|
+
for (const record of this.records.values()) record.baseURL === baseURL && result.push(record);
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
async write(records) {
|
|
11
|
+
for (const record of records) this.records.set(recordMapKey(record.baseURL, record.kind, record.id), record);
|
|
12
|
+
}
|
|
13
|
+
async remove(baseURL, keys) {
|
|
14
|
+
for (const [kind, id] of keys) this.records.delete(recordMapKey(baseURL, kind, id));
|
|
15
|
+
}
|
|
16
|
+
async clear(baseURL) {
|
|
17
|
+
if (baseURL === void 0) {
|
|
18
|
+
this.records.clear();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const [key, record] of this.records) record.baseURL === baseURL && this.records.delete(key);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
function recordMapKey(baseURL, kind, id) {
|
|
25
|
+
return `${baseURL}\0${kind}\0${id}`;
|
|
26
|
+
}
|
|
27
|
+
var IdbMetadataStore = class {
|
|
28
|
+
db;
|
|
29
|
+
kind = "indexeddb";
|
|
30
|
+
constructor(db) {
|
|
31
|
+
this.db = db;
|
|
32
|
+
}
|
|
33
|
+
readAll(baseURL) {
|
|
34
|
+
return this.transact("readonly", (store) => {
|
|
35
|
+
const range = IDBKeyRange.bound([baseURL], [baseURL, []], !1, !0);
|
|
36
|
+
return store.getAll(range);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
write(records) {
|
|
40
|
+
return records.length ? this.transact("readwrite", (store) => {
|
|
41
|
+
let last = store.put(records[0]);
|
|
42
|
+
for (let i = 1; i < records.length; i++) last = store.put(records[i]);
|
|
43
|
+
return last;
|
|
44
|
+
}).then(() => {
|
|
45
|
+
}) : Promise.resolve();
|
|
46
|
+
}
|
|
47
|
+
remove(baseURL, keys) {
|
|
48
|
+
return keys.length ? this.transact("readwrite", (store) => {
|
|
49
|
+
let last = store.delete([
|
|
50
|
+
baseURL,
|
|
51
|
+
keys[0][0],
|
|
52
|
+
keys[0][1]
|
|
53
|
+
]);
|
|
54
|
+
for (let i = 1; i < keys.length; i++) last = store.delete([
|
|
55
|
+
baseURL,
|
|
56
|
+
keys[i][0],
|
|
57
|
+
keys[i][1]
|
|
58
|
+
]);
|
|
59
|
+
return last;
|
|
60
|
+
}).then(() => {
|
|
61
|
+
}) : Promise.resolve();
|
|
62
|
+
}
|
|
63
|
+
clear(baseURL) {
|
|
64
|
+
return this.transact("readwrite", (store) => baseURL === void 0 ? store.clear() : store.delete(IDBKeyRange.bound([baseURL], [baseURL, []], !1, !0))).then(() => {
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
transact(mode, run) {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
let transaction;
|
|
70
|
+
try {
|
|
71
|
+
transaction = this.db.transaction(OBJECT_STORE, mode);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return reject(error);
|
|
74
|
+
}
|
|
75
|
+
let result;
|
|
76
|
+
try {
|
|
77
|
+
const request = run(transaction.objectStore(OBJECT_STORE));
|
|
78
|
+
request.onsuccess = () => result = request.result;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
return transaction.abort(), reject(error);
|
|
81
|
+
}
|
|
82
|
+
transaction.oncomplete = () => resolve(result), transaction.onabort = () => reject(transaction.error ?? /* @__PURE__ */ new Error("mion metadata cache transaction aborted")), transaction.onerror = () => reject(transaction.error ?? /* @__PURE__ */ new Error("mion metadata cache transaction failed"));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
function openDatabase() {
|
|
87
|
+
return typeof indexedDB > "u" ? Promise.resolve(void 0) : new Promise((resolve) => {
|
|
88
|
+
let settled = !1;
|
|
89
|
+
const settle = (db) => {
|
|
90
|
+
settled || (settled = !0, resolve(db));
|
|
91
|
+
}, timer = setTimeout(() => settle(void 0), OPEN_TIMEOUT_MS), done = (db) => {
|
|
92
|
+
clearTimeout(timer), settle(db);
|
|
93
|
+
};
|
|
94
|
+
let request;
|
|
95
|
+
try {
|
|
96
|
+
request = indexedDB.open(STORAGE_KEY, DB_VERSION);
|
|
97
|
+
} catch {
|
|
98
|
+
return clearTimeout(timer), settle(void 0);
|
|
99
|
+
}
|
|
100
|
+
request.onupgradeneeded = () => {
|
|
101
|
+
const db = request.result;
|
|
102
|
+
db.objectStoreNames.contains(OBJECT_STORE) && db.deleteObjectStore(OBJECT_STORE), db.createObjectStore(OBJECT_STORE, { keyPath: [
|
|
103
|
+
"baseURL",
|
|
104
|
+
"kind",
|
|
105
|
+
"id"
|
|
106
|
+
] });
|
|
107
|
+
}, request.onsuccess = () => {
|
|
108
|
+
const db = request.result;
|
|
109
|
+
db.onversionchange = () => db.close(), done(db);
|
|
110
|
+
}, request.onerror = () => done(void 0), request.onblocked = () => done(void 0);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async function openEngine(engine) {
|
|
114
|
+
if (engine === "memory") return new MemoryMetadataStore();
|
|
115
|
+
if (engine === "indexeddb") {
|
|
116
|
+
const db = await openDatabase();
|
|
117
|
+
return db ? new IdbMetadataStore(db) : new MemoryMetadataStore();
|
|
118
|
+
}
|
|
119
|
+
return await engine() ?? new MemoryMetadataStore();
|
|
120
|
+
}
|
|
121
|
+
function getRegistry() {
|
|
122
|
+
let registry = globalThis[STORE_GLOBAL_KEY];
|
|
123
|
+
return registry || (registry = { byEngine: /* @__PURE__ */ new Map() }, globalThis[STORE_GLOBAL_KEY] = registry), registry;
|
|
124
|
+
}
|
|
125
|
+
function getMetadataStore(engine = DEFAULT_STORAGE_ENGINE) {
|
|
126
|
+
const registry = getRegistry();
|
|
127
|
+
if (registry.override) return registry.override;
|
|
128
|
+
const existing = registry.byEngine.get(engine);
|
|
129
|
+
if (existing) return existing;
|
|
130
|
+
const pending = openEngine(engine).catch(() => new MemoryMetadataStore());
|
|
131
|
+
return registry.byEngine.set(engine, pending), pending;
|
|
132
|
+
}
|
|
133
|
+
function setMetadataStoreForTesting(store) {
|
|
134
|
+
getRegistry().override = Promise.resolve(store);
|
|
135
|
+
}
|
|
136
|
+
async function resetMetadataStore() {
|
|
137
|
+
const registry = globalThis[STORE_GLOBAL_KEY];
|
|
138
|
+
if (delete globalThis[STORE_GLOBAL_KEY], !registry) return;
|
|
139
|
+
const pending = [registry.override, ...registry.byEngine.values()].filter((entry) => entry !== void 0);
|
|
140
|
+
for (const entry of pending) await (await entry.catch(() => {
|
|
141
|
+
}))?.clear().catch(() => {
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
export {
|
|
145
|
+
IdbMetadataStore,
|
|
146
|
+
MemoryMetadataStore,
|
|
147
|
+
getMetadataStore,
|
|
148
|
+
resetMetadataStore,
|
|
149
|
+
setMetadataStoreForTesting
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=metadataStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadataStore.js","names":[],"sources":["../../../../src/lib/metadataStore.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\n// The engines mion ships, and the one place an engine is chosen. The contract they implement, and\n// that an app's own engine implements, is in storage.ts.\n\nimport {DEFAULT_STORAGE_ENGINE, STORAGE_KEY} from '../constants.ts';\nimport type {MetadataKind, MetadataRecord, MetadataRecordKey, MetadataStore, StorageEngine} from './storage.ts';\n\nconst STORE_GLOBAL_KEY = '__mion_metadata_store__';\nconst OBJECT_STORE = 'metadata';\nconst DB_VERSION = 1;\n/** A store that never answers (private mode has historically hung on open) must not hang the client */\nconst OPEN_TIMEOUT_MS = 3000;\n\n/** In-memory store for SSR, Node, and any browser where IndexedDB is missing or blocked. */\nexport class MemoryMetadataStore implements MetadataStore {\n readonly kind = 'memory' as const;\n private readonly records = new Map<string, MetadataRecord>();\n\n async readAll(baseURL: string): Promise<MetadataRecord[]> {\n const result: MetadataRecord[] = [];\n for (const record of this.records.values()) if (record.baseURL === baseURL) result.push(record);\n return result;\n }\n\n async write(records: MetadataRecord[]): Promise<void> {\n for (const record of records) this.records.set(recordMapKey(record.baseURL, record.kind, record.id), record);\n }\n\n async remove(baseURL: string, keys: MetadataRecordKey[]): Promise<void> {\n for (const [kind, id] of keys) this.records.delete(recordMapKey(baseURL, kind, id));\n }\n\n async clear(baseURL?: string): Promise<void> {\n if (baseURL === undefined) {\n this.records.clear();\n return;\n }\n for (const [key, record] of this.records) if (record.baseURL === baseURL) this.records.delete(key);\n }\n}\n\nfunction recordMapKey(baseURL: string, kind: MetadataKind, id: string): string {\n // \\u0000 as the escape, never a raw NUL byte: a source file carrying one is a repo contract break\n return `${baseURL}\\u0000${kind}\\u0000${id}`;\n}\n\n/** IndexedDB store: one object store keyed by the compound `[baseURL, kind, id]`, so every entry of\n * one server sits in one contiguous key range and a cold load is a single `getAll` over it. */\nexport class IdbMetadataStore implements MetadataStore {\n readonly kind = 'indexeddb' as const;\n constructor(private readonly db: IDBDatabase) {}\n\n readAll(baseURL: string): Promise<MetadataRecord[]> {\n return this.transact('readonly', (store) => {\n // IndexedDB orders keys by type and an array sorts after every string, so `[baseURL, []]` is a\n // valid open upper bound: strictly greater than every `[baseURL, kind, id]` and less than the\n // next baseURL. That is what keeps this ONE request instead of a cursor walk or a full scan.\n const range = IDBKeyRange.bound([baseURL], [baseURL, []], false, true);\n return store.getAll(range) as IDBRequest<MetadataRecord[]>;\n });\n }\n\n write(records: MetadataRecord[]): Promise<void> {\n if (!records.length) return Promise.resolve();\n return this.transact('readwrite', (store) => {\n let last: IDBRequest = store.put(records[0]);\n for (let i = 1; i < records.length; i++) last = store.put(records[i]);\n return last;\n }).then(() => undefined);\n }\n\n remove(baseURL: string, keys: MetadataRecordKey[]): Promise<void> {\n if (!keys.length) return Promise.resolve();\n return this.transact('readwrite', (store) => {\n let last: IDBRequest = store.delete([baseURL, keys[0][0], keys[0][1]]);\n for (let i = 1; i < keys.length; i++) last = store.delete([baseURL, keys[i][0], keys[i][1]]);\n return last;\n }).then(() => undefined);\n }\n\n clear(baseURL?: string): Promise<void> {\n return this.transact('readwrite', (store) => {\n if (baseURL === undefined) return store.clear();\n return store.delete(IDBKeyRange.bound([baseURL], [baseURL, []], false, true));\n }).then(() => undefined);\n }\n\n /** Resolves on transaction COMPLETE, not on request success: a put that succeeded inside a\n * transaction the browser then aborts (quota) must reject, or a caller would count it as stored. */\n private transact<T>(mode: IDBTransactionMode, run: (store: IDBObjectStore) => IDBRequest<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let transaction: IDBTransaction;\n try {\n transaction = this.db.transaction(OBJECT_STORE, mode);\n } catch (error) {\n return reject(error);\n }\n let result: T;\n try {\n const request = run(transaction.objectStore(OBJECT_STORE));\n request.onsuccess = () => (result = request.result);\n } catch (error) {\n transaction.abort();\n return reject(error);\n }\n transaction.oncomplete = () => resolve(result);\n transaction.onabort = () => reject(transaction.error ?? new Error('mion metadata cache transaction aborted'));\n transaction.onerror = () => reject(transaction.error ?? new Error('mion metadata cache transaction failed'));\n });\n }\n}\n\n/** Opens the database, or resolves undefined for every reason a browser can refuse one. */\nfunction openDatabase(): Promise<IDBDatabase | undefined> {\n if (typeof indexedDB === 'undefined') return Promise.resolve(undefined);\n return new Promise<IDBDatabase | undefined>((resolve) => {\n let settled = false;\n const settle = (db?: IDBDatabase) => {\n if (settled) return;\n settled = true;\n resolve(db);\n };\n // an open that never answers falls back rather than hanging the first call behind it\n const timer = setTimeout(() => settle(undefined), OPEN_TIMEOUT_MS);\n const done = (db?: IDBDatabase) => {\n clearTimeout(timer);\n settle(db);\n };\n let request: IDBOpenDBRequest;\n try {\n request = indexedDB.open(STORAGE_KEY, DB_VERSION);\n } catch {\n clearTimeout(timer);\n return settle(undefined);\n }\n request.onupgradeneeded = () => {\n const db = request.result;\n // the cache holds nothing that is not refetchable, so a schema bump is the invalidation lever\n if (db.objectStoreNames.contains(OBJECT_STORE)) db.deleteObjectStore(OBJECT_STORE);\n db.createObjectStore(OBJECT_STORE, {keyPath: ['baseURL', 'kind', 'id']});\n };\n request.onsuccess = () => {\n const db = request.result;\n // another tab upgrading must not deadlock this one: close and let the next call fall back\n db.onversionchange = () => db.close();\n done(db);\n };\n request.onerror = () => done(undefined);\n request.onblocked = () => done(undefined);\n });\n}\n\n/** Opens one engine. Anything it cannot give us here is a cache miss, never a failed call, so every\n * refusal lands on the same fallback: keep the cache in memory for the life of the process. */\nasync function openEngine(engine: StorageEngine): Promise<MetadataStore> {\n if (engine === 'memory') return new MemoryMetadataStore();\n if (engine === 'indexeddb') {\n const db = await openDatabase();\n return db ? new IdbMetadataStore(db) : new MemoryMetadataStore();\n }\n // an app's own engine\n return (await engine()) ?? new MemoryMetadataStore();\n}\n\n/** One resolved store per engine, plus a stand-in that wins over all of them while testing.\n * Memoized on globalThis so every module instance shares one connection. */\ninterface StoreRegistry {\n override?: Promise<MetadataStore>;\n byEngine: Map<StorageEngine, Promise<MetadataStore>>;\n}\n\nfunction getRegistry(): StoreRegistry {\n let registry = (globalThis as any)[STORE_GLOBAL_KEY] as StoreRegistry | undefined;\n if (!registry) {\n registry = {byEngine: new Map()};\n (globalThis as any)[STORE_GLOBAL_KEY] = registry;\n }\n return registry;\n}\n\n/** Returns the store for one engine, opening it on first use. */\nexport function getMetadataStore(engine: StorageEngine = DEFAULT_STORAGE_ENGINE): Promise<MetadataStore> {\n const registry = getRegistry();\n if (registry.override) return registry.override;\n const existing = registry.byEngine.get(engine);\n if (existing) return existing;\n const pending = openEngine(engine).catch(() => new MemoryMetadataStore());\n registry.byEngine.set(engine, pending);\n return pending;\n}\n\n/** Puts a stand-in behind every engine. Only for testing — the browser's own limits (a full disk, a\n * refused write) cannot be produced any other way. */\nexport function setMetadataStoreForTesting(store: MetadataStore): void {\n getRegistry().override = Promise.resolve(store);\n}\n\n/** Drops every store instance and everything they hold. Only for testing — simulates a new page. */\nexport async function resetMetadataStore(): Promise<void> {\n const registry = (globalThis as any)[STORE_GLOBAL_KEY] as StoreRegistry | undefined;\n delete (globalThis as any)[STORE_GLOBAL_KEY];\n if (!registry) return;\n const pending = [registry.override, ...registry.byEngine.values()].filter((entry) => entry !== undefined);\n for (const entry of pending) {\n const store = await entry.catch(() => undefined);\n await store?.clear().catch(() => undefined);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MethodWithOptions, MethodWithOptsAndJitFns } from '@mionjs/core';
|
|
2
|
+
export interface FetchedMethods {
|
|
3
|
+
hasMetadata(id: string): boolean;
|
|
4
|
+
getMetadata(id: string): MethodWithOptions | undefined;
|
|
5
|
+
useMethodJitFns(id: string): MethodWithOptsAndJitFns;
|
|
6
|
+
}
|
|
7
|
+
export declare function hasMethod(id: string): boolean;
|
|
8
|
+
export declare function getMethod(id: string): MethodWithOptions | undefined;
|
|
9
|
+
export declare function useMethodFns(id: string): MethodWithOptsAndJitFns;
|
|
10
|
+
export declare function setBundledMethod(id: string, entry: MethodWithOptsAndJitFns): void;
|
|
11
|
+
export declare function isBundledMethod(id: string): boolean;
|
|
12
|
+
export declare function bundledMethodIds(): string[];
|
|
13
|
+
export declare function setFetchedMethods(methods: FetchedMethods): void;
|
|
14
|
+
export declare function resetBundledMethods(): void;
|
|
15
|
+
//# sourceMappingURL=methods.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var bundledMethods = /* @__PURE__ */ new Map(), fetchedMethods;
|
|
2
|
+
function hasMethod(id) {
|
|
3
|
+
return bundledMethods.has(id) || fetchedMethods?.hasMetadata(id) === !0;
|
|
4
|
+
}
|
|
5
|
+
function getMethod(id) {
|
|
6
|
+
return bundledMethods.get(id) ?? fetchedMethods?.getMetadata(id);
|
|
7
|
+
}
|
|
8
|
+
function useMethodFns(id) {
|
|
9
|
+
const bundled = bundledMethods.get(id);
|
|
10
|
+
if (bundled) return bundled;
|
|
11
|
+
const fetched = fetchedMethods?.useMethodJitFns(id);
|
|
12
|
+
if (!fetched) throw new Error(`Metadata for remote method ${id} not found`);
|
|
13
|
+
return fetched;
|
|
14
|
+
}
|
|
15
|
+
function setBundledMethod(id, entry) {
|
|
16
|
+
bundledMethods.set(id, entry);
|
|
17
|
+
}
|
|
18
|
+
function isBundledMethod(id) {
|
|
19
|
+
return bundledMethods.has(id);
|
|
20
|
+
}
|
|
21
|
+
function bundledMethodIds() {
|
|
22
|
+
return [...bundledMethods.keys()];
|
|
23
|
+
}
|
|
24
|
+
function setFetchedMethods(methods) {
|
|
25
|
+
fetchedMethods = methods;
|
|
26
|
+
}
|
|
27
|
+
function resetBundledMethods() {
|
|
28
|
+
bundledMethods.clear();
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
bundledMethodIds,
|
|
32
|
+
getMethod,
|
|
33
|
+
hasMethod,
|
|
34
|
+
isBundledMethod,
|
|
35
|
+
resetBundledMethods,
|
|
36
|
+
setBundledMethod,
|
|
37
|
+
setFetchedMethods,
|
|
38
|
+
useMethodFns
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=methods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methods.js","names":[],"sources":["../../../../src/lib/methods.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {MethodWithOptions, MethodWithOptsAndJitFns} from '@mionjs/core';\n\n// The only method table the request path knows: the bundle's own rows, and the fetched lane's\n// (core's routesCache) once that lane loads. Keeping them apart leaves the routes cache out of a\n// bundled build, and stops a fetched or restored row ever landing on an id the build compiled.\n\n/** What the fetched lane answers with; `routesCache` implements it as-is. */\nexport interface FetchedMethods {\n hasMetadata(id: string): boolean;\n getMetadata(id: string): MethodWithOptions | undefined;\n useMethodJitFns(id: string): MethodWithOptsAndJitFns;\n}\n\nconst bundledMethods = new Map<string, MethodWithOptsAndJitFns>();\nlet fetchedMethods: FetchedMethods | undefined;\n\nexport function hasMethod(id: string): boolean {\n return bundledMethods.has(id) || fetchedMethods?.hasMetadata(id) === true;\n}\n\nexport function getMethod(id: string): MethodWithOptions | undefined {\n return bundledMethods.get(id) ?? fetchedMethods?.getMetadata(id);\n}\n\n/** Row plus compiled functions; throws when neither shelf holds it, as `routesCache.useMethodJitFns` does. */\nexport function useMethodFns(id: string): MethodWithOptsAndJitFns {\n const bundled = bundledMethods.get(id);\n if (bundled) return bundled;\n const fetched = fetchedMethods?.useMethodJitFns(id);\n if (!fetched) throw new Error(`Metadata for remote method ${id} not found`);\n return fetched;\n}\n\n/** Puts a build-compiled method on the bundled shelf. Only `registerBundledApi` calls this. */\nexport function setBundledMethod(id: string, entry: MethodWithOptsAndJitFns): void {\n bundledMethods.set(id, entry);\n}\n\nexport function isBundledMethod(id: string): boolean {\n return bundledMethods.has(id);\n}\n\n/** Every id the bundle carries: what the version-mismatch lane offers the server, and what tests read. */\nexport function bundledMethodIds(): string[] {\n return [...bundledMethods.keys()];\n}\n\n/** Hands the fetched lane's table over, once, as that lane loads. */\nexport function setFetchedMethods(methods: FetchedMethods): void {\n fetchedMethods = methods;\n}\n\n/** Empties the bundled shelf. Tests only: the fetched shelf stays wired, the lane module evaluates once. */\nexport function resetBundledMethods(): void {\n bundledMethods.clear();\n}\n"],"mappings":"AAoBA,IAAM,iBAAiB,oBAAI,IAAqC,GAC5D;AAEJ,SAAgB,UAAU,IAAqB;AAC7C,SAAO,eAAe,IAAI,EAAE,KAAK,gBAAgB,YAAY,EAAE,MAAM;AACvE;AAEA,SAAgB,UAAU,IAA2C;AACnE,SAAO,eAAe,IAAI,EAAE,KAAK,gBAAgB,YAAY,EAAE;AACjE;AAGA,SAAgB,aAAa,IAAqC;AAChE,QAAM,UAAU,eAAe,IAAI,EAAE;AACrC,MAAI,QAAS,QAAO;AACpB,QAAM,UAAU,gBAAgB,gBAAgB,EAAE;AAClD,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,8BAA8B,EAAA,YAAc;AAC1E,SAAO;AACT;AAGA,SAAgB,iBAAiB,IAAY,OAAsC;AACjF,iBAAe,IAAI,IAAI,KAAK;AAC9B;AAEA,SAAgB,gBAAgB,IAAqB;AACnD,SAAO,eAAe,IAAI,EAAE;AAC9B;AAGA,SAAgB,mBAA6B;AAC3C,SAAO,CAAC,GAAG,eAAe,KAAK,CAAC;AAClC;AAGA,SAAgB,kBAAkB,SAA+B;AAC/D,mBAAiB;AACnB;AAGA,SAAgB,sBAA4B;AAC1C,iBAAe,MAAM;AACvB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
async function requestPersistentStorage() {
|
|
2
|
+
const storage = globalThis.navigator?.storage;
|
|
3
|
+
if (!storage?.persist) return !1;
|
|
4
|
+
try {
|
|
5
|
+
return await storage.persisted?.() ? !0 : await storage.persist();
|
|
6
|
+
} catch {
|
|
7
|
+
return !1;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async function requestPersistenceWhenSilent() {
|
|
11
|
+
const storage = globalThis.navigator?.storage;
|
|
12
|
+
if (!storage?.persist || !storage.persisted) return !1;
|
|
13
|
+
try {
|
|
14
|
+
if (await storage.persisted()) return !0;
|
|
15
|
+
const permissions = globalThis.navigator?.permissions;
|
|
16
|
+
return !permissions?.query || (await permissions.query({ name: "persistent-storage" })).state !== "granted" ? !1 : await storage.persist();
|
|
17
|
+
} catch {
|
|
18
|
+
return !1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
requestPersistenceWhenSilent,
|
|
23
|
+
requestPersistentStorage
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=persistentStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistentStorage.js","names":[],"sources":["../../../../src/lib/persistentStorage.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\n/** Asks the browser to keep the metadata cache when it starts clearing storage to reclaim space.\n * Call it from your own code, ideally after a user action: some browsers show a permission bar for\n * this, so mion never calls it on your behalf unless the permission is already granted.\n * Resolves false where the browser has no such notion. */\nexport async function requestPersistentStorage(): Promise<boolean> {\n const storage = globalThis.navigator?.storage;\n if (!storage?.persist) return false;\n try {\n if (await storage.persisted?.()) return true;\n return await storage.persist();\n } catch {\n return false;\n }\n}\n\n/** The automatic half, run once after the cache's first successful write. mion NEVER triggers a browser\n * prompt: `persist()` can show a permission bar and no one can tell in advance which browser will, so this\n * asks only from `granted`. Anywhere else the cache is simply evictable, until an app asks for itself. */\nexport async function requestPersistenceWhenSilent(): Promise<boolean> {\n const storage = globalThis.navigator?.storage;\n if (!storage?.persist || !storage.persisted) return false;\n try {\n if (await storage.persisted()) return true;\n const permissions = globalThis.navigator?.permissions;\n if (!permissions?.query) return false;\n const status = await permissions.query({name: 'persistent-storage' as PermissionName});\n if (status.state !== 'granted') return false;\n return await storage.persist();\n } catch {\n // an unsupported permission name rejects; that is a browser we do not ask in\n return false;\n }\n}\n"],"mappings":"AAWA,eAAsB,2BAA6C;AACjE,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS,QAAS,QAAO;AAC9B,MAAI;AACF,WAAI,MAAM,QAAQ,YAAY,IAAU,KACjC,MAAM,QAAQ,QAAQ;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,+BAAiD;AACrE,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS,WAAW,CAAC,QAAQ,UAAW,QAAO;AACpD,MAAI;AACF,QAAI,MAAM,QAAQ,UAAU,EAAG,QAAO;AACtC,UAAM,cAAc,WAAW,WAAW;AAG1C,WAFI,CAAC,aAAa,UAEd,MADiB,YAAY,MAAM,EAAC,MAAM,qBAAsC,CAAC,GAC1E,UAAU,YAAkB,KAChC,MAAM,QAAQ,QAAQ;AAAA,EAC/B,QAAQ;AAEN,WAAO;AAAA,EACT;AACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { hasMethod, useMethodFns } from "./methods.js";
|
|
2
|
+
import { HandlerType } from "@mionjs/core";
|
|
3
|
+
var sanitizedParams = /* @__PURE__ */ new WeakSet();
|
|
4
|
+
function sanitizeSubRequests(subRequestIds, context) {
|
|
5
|
+
if (context.options.sanitizeParams)
|
|
6
|
+
for (const id of subRequestIds) {
|
|
7
|
+
const subRequest = context.subRequestList[id];
|
|
8
|
+
if (!subRequest || subRequest.isResolved || subRequest.error) continue;
|
|
9
|
+
const params = subRequest.params;
|
|
10
|
+
if (!Array.isArray(params) || sanitizedParams.has(params) || subRequest.mappings && subRequest.mappings.length > 0 || !hasMethod(id)) continue;
|
|
11
|
+
const method = useMethodFns(id), formatTransform = method.paramsJitFns.formatTransform;
|
|
12
|
+
if (!method.options?.sanitizeParams || !method.paramsCount || !formatTransform || formatTransform.isNoop) continue;
|
|
13
|
+
const isHeadersMiddleware = method.type === HandlerType.headersMiddleware && !!method.headersParam, body = isHeadersMiddleware ? params.slice(1) : params;
|
|
14
|
+
try {
|
|
15
|
+
const sanitized = formatTransform.fn(body);
|
|
16
|
+
subRequest.params = isHeadersMiddleware ? [params[0], ...sanitized] : sanitized, sanitizedParams.add(subRequest.params);
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
sanitizeSubRequests
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","names":[],"sources":["../../../../src/lib/sanitize.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {HandlerType} from '@mionjs/core';\nimport {hasMethod, useMethodFns} from './methods.ts';\nimport type {CallContext} from '../types.ts';\n\n// A retry sanitizes the same params again, and a first-match `replace` must not run twice on them.\nconst sanitizedParams = new WeakSet<any[]>();\n\n/** Runs before validation and serialization, so the client sends what the server sees; never throws, validation reports bad input */\nexport function sanitizeSubRequests(subRequestIds: string[], context: CallContext): void {\n if (!context.options.sanitizeParams) return;\n for (const id of subRequestIds) {\n const subRequest = context.subRequestList[id];\n if (!subRequest || subRequest.isResolved || subRequest.error) continue;\n const params = subRequest.params;\n if (!Array.isArray(params) || sanitizedParams.has(params)) continue;\n // inputFrom placeholders are filled by the server after the source route runs\n if (subRequest.mappings && subRequest.mappings.length > 0) continue;\n if (!hasMethod(id)) continue;\n const method = useMethodFns(id);\n const formatTransform = method.paramsJitFns.formatTransform;\n if (!method.options?.sanitizeParams || !method.paramsCount || !formatTransform || formatTransform.isNoop) continue;\n // a headersMiddleware's first param is the HeadersSubset, never part of the body params type\n const isHeadersMiddleware = method.type === HandlerType.headersMiddleware && !!method.headersParam;\n const body = isHeadersMiddleware ? params.slice(1) : params;\n try {\n const sanitized = formatTransform.fn(body) as any[];\n subRequest.params = isHeadersMiddleware ? [params[0], ...sanitized] : sanitized;\n sanitizedParams.add(subRequest.params);\n } catch {\n // validation reports the real error\n }\n }\n}\n"],"mappings":";;AAYA,IAAM,kBAAkB,oBAAI,QAAe;AAG3C,SAAgB,oBAAoB,eAAyB,SAA4B;AACvF,MAAK,QAAQ,QAAQ;AACrB,eAAW,MAAM,eAAe;AAC9B,YAAM,aAAa,QAAQ,eAAe,EAAA;AAC1C,UAAI,CAAC,cAAc,WAAW,cAAc,WAAW,MAAO;AAC9D,YAAM,SAAS,WAAW;AAI1B,UAHI,CAAC,MAAM,QAAQ,MAAM,KAAK,gBAAgB,IAAI,MAAM,KAEpD,WAAW,YAAY,WAAW,SAAS,SAAS,KACpD,CAAC,UAAU,EAAE,EAAG;AACpB,YAAM,SAAS,aAAa,EAAE,GACxB,kBAAkB,OAAO,aAAa;AAC5C,UAAI,CAAC,OAAO,SAAS,kBAAkB,CAAC,OAAO,eAAe,CAAC,mBAAmB,gBAAgB,OAAQ;AAE1G,YAAM,sBAAsB,OAAO,SAAS,YAAY,qBAAqB,CAAC,CAAC,OAAO,cAChF,OAAO,sBAAsB,OAAO,MAAM,CAAC,IAAI;AACrD,UAAI;AACF,cAAM,YAAY,gBAAgB,GAAG,IAAI;AACzC,mBAAW,SAAS,sBAAsB,CAAC,OAAO,CAAA,GAAI,GAAG,SAAS,IAAI,WACtE,gBAAgB,IAAI,WAAW,MAAM;AAAA,MACvC,QAAQ;AAAA,MAER;AAAA,IACF;AACF"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { ResponseBody } from '@mionjs/router';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export type
|
|
5
|
-
|
|
2
|
+
import { CallContext, ClientOptions } from '../types.ts';
|
|
3
|
+
export type SerializedBody = string;
|
|
4
|
+
export type ContentType = 'application/json; charset=utf-8';
|
|
5
|
+
type TakeRaw = (parsedBody: Record<string, unknown>) => Record<string, unknown> | undefined;
|
|
6
6
|
export interface SerializedRequest {
|
|
7
7
|
body: SerializedBody;
|
|
8
8
|
contentType: ContentType;
|
|
9
9
|
}
|
|
10
|
-
export declare function serializeRequestBody(
|
|
11
|
-
export declare function
|
|
10
|
+
export declare function serializeRequestBody(context: CallContext, optimistic?: boolean): SerializedRequest;
|
|
11
|
+
export declare function wireFormReplacer(this: unknown, key: string, value: unknown): unknown;
|
|
12
|
+
export declare function deserializeResponseBody(response: Response, options: ClientOptions, takeRaw?: TakeRaw): Promise<ResponseBody>;
|
|
13
|
+
export {};
|
|
12
14
|
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -1,42 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
function serializeRequestBody(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
body: serializeJsonBody(req),
|
|
11
|
-
contentType: "application/json; charset=utf-8"
|
|
12
|
-
};
|
|
13
|
-
case "optimistic":
|
|
14
|
-
return {
|
|
15
|
-
body: serializeJSonBodyOptimistic(req),
|
|
16
|
-
contentType: "application/json; charset=utf-8"
|
|
17
|
-
};
|
|
18
|
-
case "binary":
|
|
19
|
-
return {
|
|
20
|
-
body: serializeBinaryBody(req),
|
|
21
|
-
contentType: "application/octet-stream"
|
|
22
|
-
};
|
|
23
|
-
default:
|
|
24
|
-
throw new Error(`Invalid serializer mode ${serializerMode}`);
|
|
25
|
-
}
|
|
1
|
+
import { useMethodFns } from "./methods.js";
|
|
2
|
+
import { hasHeadersSubsetParam } from "./headers.js";
|
|
3
|
+
import { HandlerType, MION_ROUTES, RpcError, isRpcError } from "@mionjs/core";
|
|
4
|
+
function serializeRequestBody(context, optimistic = !1) {
|
|
5
|
+
return {
|
|
6
|
+
body: optimistic ? serializeJSonBodyOptimistic(context) : serializeJsonBody(context),
|
|
7
|
+
contentType: "application/json; charset=utf-8"
|
|
8
|
+
};
|
|
26
9
|
}
|
|
27
|
-
function serializeJsonBody(
|
|
28
|
-
const props = [], subRequestIds = Object.keys(
|
|
10
|
+
function serializeJsonBody(context) {
|
|
11
|
+
const props = [], subRequestIds = Object.keys(context.subRequestList);
|
|
29
12
|
for (let i = 0; i < subRequestIds.length; i++) {
|
|
30
|
-
const id = subRequestIds[i], subRequest =
|
|
31
|
-
if (!subRequest)
|
|
32
|
-
continue;
|
|
13
|
+
const id = subRequestIds[i], subRequest = context.subRequestList[id];
|
|
14
|
+
if (!subRequest) continue;
|
|
33
15
|
let params = subRequest.params;
|
|
34
|
-
const method =
|
|
35
|
-
method.type === HandlerType.
|
|
16
|
+
const method = useMethodFns(id);
|
|
17
|
+
method.type === HandlerType.headersMiddleware && method.headersParam && (params = getParamsWithoutHeadersSubset(params));
|
|
36
18
|
try {
|
|
37
|
-
const jsonValue = stringifyHandlerParams(method, params);
|
|
38
|
-
if (!jsonValue)
|
|
39
|
-
continue;
|
|
19
|
+
const jsonValue = stringifyHandlerParams(method, params, context.options.validateParams);
|
|
20
|
+
if (!jsonValue) continue;
|
|
40
21
|
props.push(`${JSON.stringify(id)}:${jsonValue}`);
|
|
41
22
|
} catch (e) {
|
|
42
23
|
throw new RpcError({
|
|
@@ -48,60 +29,61 @@ function serializeJsonBody(req) {
|
|
|
48
29
|
}
|
|
49
30
|
return `{${props.join(",")}}`;
|
|
50
31
|
}
|
|
51
|
-
function serializeJSonBodyOptimistic(
|
|
52
|
-
const body = {}, subRequestIds = Object.keys(
|
|
32
|
+
function serializeJSonBodyOptimistic(context) {
|
|
33
|
+
const body = {}, subRequestIds = Object.keys(context.subRequestList);
|
|
53
34
|
for (const id of subRequestIds) {
|
|
54
|
-
const subRequest =
|
|
55
|
-
|
|
35
|
+
const subRequest = context.subRequestList[id];
|
|
36
|
+
if (!subRequest) continue;
|
|
37
|
+
const params = hasHeadersSubsetParam(id, subRequest.params) ? getParamsWithoutHeadersSubset(subRequest.params) : subRequest.params;
|
|
38
|
+
params?.length && (body[id] = params);
|
|
56
39
|
}
|
|
57
|
-
return JSON.stringify(body);
|
|
40
|
+
return JSON.stringify(body, wireFormReplacer);
|
|
58
41
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
function stringifyHandlerParams(method, params, validated) {
|
|
43
|
+
if (!method.paramsCount) return "";
|
|
44
|
+
const { json, isType } = method.paramsJitFns;
|
|
45
|
+
if (json.encode.isNoop) return JSON.stringify(params);
|
|
46
|
+
if (!validated && !isType.isNoop && !isType.fn(params)) return JSON.stringify(params, wireFormReplacer);
|
|
47
|
+
const write = () => JSON.stringify(json.encode.fn(params));
|
|
48
|
+
try {
|
|
49
|
+
return write();
|
|
50
|
+
} catch {
|
|
51
|
+
return JSON.stringify(params, wireFormReplacer);
|
|
65
52
|
}
|
|
66
|
-
const workflowRouteIds = req.workflowSubRequests?.map((sr) => sr.id), { buffer } = serializeBinaryBody$1(req.path, executionChain, body, !1, workflowRouteIds);
|
|
67
|
-
return new Uint8Array(buffer);
|
|
68
53
|
}
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
return "";
|
|
72
|
-
const paramsJit = method.paramsJitFns;
|
|
73
|
-
return paramsJit.prepareForJson.isNoop ? JSON.stringify(params) : paramsJit.stringifyJson.fn(params);
|
|
54
|
+
function wireFormReplacer(key, value) {
|
|
55
|
+
return value instanceof Map ? [...value] : value instanceof Set ? [...value] : typeof value == "bigint" ? value.toString() : value;
|
|
74
56
|
}
|
|
75
|
-
async function deserializeResponseBody(response, options) {
|
|
57
|
+
async function deserializeResponseBody(response, options, takeRaw) {
|
|
76
58
|
let parsedBody;
|
|
77
59
|
const contentType = response.headers.get("content-type")?.toLowerCase();
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
default:
|
|
86
|
-
throw new RpcError({
|
|
87
|
-
type: "unsupported-content-type",
|
|
88
|
-
publicMessage: `Unsupported response content-type: '${contentType || "none"}'`
|
|
89
|
-
});
|
|
90
|
-
}
|
|
60
|
+
if (!0 === !!contentType?.includes("application/json"))
|
|
61
|
+
parsedBody = await deserializeJsonResponseBody(response, takeRaw);
|
|
62
|
+
else
|
|
63
|
+
throw new RpcError({
|
|
64
|
+
type: "unsupported-content-type",
|
|
65
|
+
publicMessage: `Unsupported response content-type: '${contentType || "none"}'`
|
|
66
|
+
});
|
|
91
67
|
return parsedBody;
|
|
92
68
|
}
|
|
93
|
-
async function deserializeJsonResponseBody(response,
|
|
69
|
+
async function deserializeJsonResponseBody(response, takeRaw) {
|
|
94
70
|
try {
|
|
95
|
-
const parsedBody = await response.json();
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (platformError)
|
|
99
|
-
return { [MION_ROUTES.platformError]: platformError };
|
|
71
|
+
const parsedBody = await response.json(), rawEntries = parsedBody && typeof parsedBody == "object" ? takeRaw?.(parsedBody) : void 0, extracted = extractThrownErrors(parsedBody);
|
|
72
|
+
if (extracted.platformError) return { [MION_ROUTES.platformError]: extracted.platformError };
|
|
73
|
+
let thrownErrors = extracted.thrownErrors;
|
|
100
74
|
const deserializedBody = {};
|
|
101
75
|
return Object.entries(parsedBody).forEach(([methodId, returnValue]) => {
|
|
102
|
-
const method =
|
|
103
|
-
|
|
104
|
-
|
|
76
|
+
const method = useMethodFns(methodId);
|
|
77
|
+
try {
|
|
78
|
+
deserializedBody[methodId] = parseHandlerJsonReturnValue(method, returnValue);
|
|
79
|
+
} catch (decodeError) {
|
|
80
|
+
(thrownErrors ??= {})[methodId] = new RpcError({
|
|
81
|
+
type: "deserialization-error",
|
|
82
|
+
publicMessage: `Invalid response from Route or Middleware '${method.id}', can not deserialize return value: ${decodeError.message}`,
|
|
83
|
+
errorData: decodeError?.errors
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}), thrownErrors && (deserializedBody[MION_ROUTES.thrownErrors] = thrownErrors), rawEntries && Object.assign(deserializedBody, rawEntries), deserializedBody;
|
|
105
87
|
} catch (err) {
|
|
106
88
|
throw new RpcError({
|
|
107
89
|
type: "parsing-json-response-error",
|
|
@@ -109,47 +91,30 @@ async function deserializeJsonResponseBody(response, options) {
|
|
|
109
91
|
});
|
|
110
92
|
}
|
|
111
93
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return;
|
|
119
|
-
const unexpectedErrors = parsedBody[MION_ROUTES.thrownErrors];
|
|
120
|
-
if (MION_ROUTES.platformError in unexpectedErrors) {
|
|
121
|
-
const globalErrorValue = unexpectedErrors[MION_ROUTES.platformError];
|
|
122
|
-
return isRpcError(globalErrorValue) ? new RpcError(globalErrorValue) : globalErrorValue;
|
|
94
|
+
function extractThrownErrors(parsedBody) {
|
|
95
|
+
if (!(MION_ROUTES.thrownErrors in parsedBody)) return {};
|
|
96
|
+
const rawThrownErrors = parsedBody[MION_ROUTES.thrownErrors];
|
|
97
|
+
if (delete parsedBody[MION_ROUTES.thrownErrors], MION_ROUTES.platformError in rawThrownErrors) {
|
|
98
|
+
const globalErrorValue = rawThrownErrors[MION_ROUTES.platformError];
|
|
99
|
+
return { platformError: isRpcError(globalErrorValue) ? new RpcError(globalErrorValue) : globalErrorValue };
|
|
123
100
|
}
|
|
124
|
-
Object.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return Object.keys(req.subRequestList).every((id) => routesCache.hasMetadata(id)) ? "stringifyJson" : "optimistic";
|
|
129
|
-
const methodId = req.route?.id ?? req.workflowSubRequests?.[0]?.id, serializerMode = routesCache.getMethodJitFns(methodId)?.options.serializer || DEFAULT_PREFILL_OPTIONS.serializer;
|
|
130
|
-
return serializerMode === "json" ? DEFAULT_PREFILL_OPTIONS.serializer : serializerMode;
|
|
101
|
+
const thrownErrors = /* @__PURE__ */ Object.create(null);
|
|
102
|
+
return Object.entries(rawThrownErrors).forEach(([id, value]) => {
|
|
103
|
+
thrownErrors[id] = isRpcError(value) ? new RpcError(value) : value;
|
|
104
|
+
}), { thrownErrors };
|
|
131
105
|
}
|
|
132
106
|
function getParamsWithoutHeadersSubset(params) {
|
|
133
107
|
return !params || params.length === 0 ? [] : params.slice(1);
|
|
134
108
|
}
|
|
135
109
|
function parseHandlerJsonReturnValue(method, returnValue) {
|
|
136
|
-
if (!method.hasReturnData)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (returnJit.restoreFromJson.isNoop || !returnValue)
|
|
140
|
-
return returnValue;
|
|
141
|
-
try {
|
|
142
|
-
return returnValue instanceof RpcError ? returnValue : isRpcError(returnValue) ? new RpcError(returnValue) : returnJit.restoreFromJson.fn(returnValue);
|
|
143
|
-
} catch (e) {
|
|
144
|
-
return new RpcError({
|
|
145
|
-
type: "deserialization-error",
|
|
146
|
-
publicMessage: `Invalid response from Route or MiddleFn '${method.id}', can not deserialize return value: ${e.message}`,
|
|
147
|
-
errorData: e?.errors
|
|
148
|
-
});
|
|
149
|
-
}
|
|
110
|
+
if (!method.hasReturnData) return returnValue;
|
|
111
|
+
const { decode } = method.returnJitFns.json;
|
|
112
|
+
return decode.isNoop || !returnValue || returnValue instanceof RpcError ? returnValue : isRpcError(returnValue) ? new RpcError(returnValue) : decode.fn(returnValue);
|
|
150
113
|
}
|
|
151
114
|
export {
|
|
152
115
|
deserializeResponseBody,
|
|
153
|
-
serializeRequestBody
|
|
116
|
+
serializeRequestBody,
|
|
117
|
+
wireFormReplacer
|
|
154
118
|
};
|
|
155
|
-
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=serializer.js.map
|