@volter/world-core 3.0.154 → 3.0.156
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/generated/pack-facts.json +140 -0
- package/dist/inject.cjs +150 -86
- package/dist/src/actions.d.ts +15 -0
- package/dist/src/actions.js +82 -21
- package/dist/src/ancestry.d.ts +5 -4
- package/dist/src/ancestry.js +53 -28
- package/dist/src/changeset.js +1 -1
- package/dist/src/clickhouse/compression.d.ts +28 -0
- package/dist/src/clickhouse/compression.js +281 -0
- package/dist/src/clickhouse/index.d.ts +1 -0
- package/dist/src/clickhouse/index.js +1 -0
- package/dist/src/client-bundle.js +15 -15
- package/dist/src/derived-core.d.ts +12 -1
- package/dist/src/derived-core.js +145 -11
- package/dist/src/derived.js +3 -0
- package/dist/src/fork.js +1 -1
- package/dist/src/graphql-wire.d.ts +5 -0
- package/dist/src/graphql-wire.js +6 -6
- package/dist/src/grpc-wire.js +2 -1
- package/dist/src/h2.js +63 -10
- package/dist/src/head.d.ts +3 -0
- package/dist/src/head.js +9 -0
- package/dist/src/history.d.ts +1 -1
- package/dist/src/history.js +7 -7
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.js +5 -1
- package/dist/src/log.d.ts +23 -3
- package/dist/src/log.js +160 -37
- package/dist/src/managed-original-inputs.d.ts +101 -0
- package/dist/src/managed-original-inputs.js +125 -0
- package/dist/src/mongodb/client.d.ts +8 -0
- package/dist/src/mongodb/client.js +27 -0
- package/dist/src/mongodb/index.d.ts +2 -0
- package/dist/src/mongodb/index.js +5 -0
- package/dist/src/mongodb/stream.d.ts +74 -0
- package/dist/src/mongodb/stream.js +206 -0
- package/dist/src/observe.js +1 -1
- package/dist/src/pack-fetch.d.ts +2 -1
- package/dist/src/pack-fetch.js +21 -9
- package/dist/src/packRegistry.d.ts +10 -14
- package/dist/src/packRegistry.js +2 -13
- package/dist/src/protocol.d.ts +13 -0
- package/dist/src/protocol.js +13 -0
- package/dist/src/redis/engine.d.ts +10 -4
- package/dist/src/redis/engine.js +103 -32
- package/dist/src/redis/member-storage.js +20 -8
- package/dist/src/redis/service-times.d.ts +25 -0
- package/dist/src/redis/service-times.js +87 -0
- package/dist/src/redis/stream.d.ts +2 -1
- package/dist/src/redis/stream.js +109 -20
- package/dist/src/runtime-state.d.ts +11 -0
- package/dist/src/runtime-state.js +13 -0
- package/dist/src/runtime.d.ts +4 -2
- package/dist/src/runtime.js +5 -2
- package/dist/src/serve-http.d.ts +2 -0
- package/dist/src/serve-http.js +21 -4
- package/dist/src/serve.d.ts +10 -0
- package/dist/src/serve.js +43 -3
- package/dist/src/storage.d.ts +2 -1
- package/dist/src/storage.js +6 -3
- package/dist/src/world-boot.d.ts +1 -0
- package/dist/src/world-boot.js +6 -0
- package/dist/src/world-clock.js +6 -2
- package/dist/src/world-store.d.ts +108 -7
- package/dist/src/world-store.js +883 -103
- package/dist/src/xml.d.ts +30 -0
- package/dist/src/xml.js +74 -0
- package/generated/pack-facts.json +140 -0
- package/inject.cjs +150 -86
- package/package.json +20 -1
- package/src/actions.ts +78 -21
- package/src/ancestry.ts +46 -24
- package/src/changeset.ts +1 -1
- package/src/clickhouse/compression.ts +172 -0
- package/src/clickhouse/index.ts +2 -0
- package/src/client-bundle.ts +13 -14
- package/src/derived-core.ts +142 -11
- package/src/derived.ts +3 -0
- package/src/fork.ts +1 -1
- package/src/graphql-wire.ts +9 -6
- package/src/grpc-wire.ts +2 -1
- package/src/h2.ts +46 -5
- package/src/head.ts +9 -0
- package/src/history.ts +7 -7
- package/src/index.ts +6 -1
- package/src/log.ts +147 -32
- package/src/managed-original-inputs.ts +163 -0
- package/src/mongodb/client.ts +27 -0
- package/src/mongodb/index.ts +5 -0
- package/src/mongodb/stream.ts +213 -0
- package/src/observe.ts +1 -1
- package/src/pack-fetch.ts +23 -11
- package/src/packRegistry.ts +3 -15
- package/src/protocol.ts +13 -0
- package/src/redis/engine.ts +100 -57
- package/src/redis/member-storage.ts +17 -9
- package/src/redis/service-times.ts +81 -0
- package/src/redis/stream.ts +66 -14
- package/src/runtime-state.ts +14 -0
- package/src/runtime.ts +6 -1
- package/src/serve-http.ts +23 -4
- package/src/serve.ts +45 -3
- package/src/storage.ts +5 -3
- package/src/world-boot.ts +6 -0
- package/src/world-clock.ts +6 -2
- package/src/world-store.ts +704 -91
- package/src/xml.ts +71 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type XmlElement = {
|
|
2
|
+
kind: 'element';
|
|
3
|
+
name: string;
|
|
4
|
+
attributes: Record<string, string>;
|
|
5
|
+
content: XmlContent[];
|
|
6
|
+
};
|
|
7
|
+
export type XmlText = {
|
|
8
|
+
kind: 'text' | 'cdata' | 'comment';
|
|
9
|
+
value: string;
|
|
10
|
+
};
|
|
11
|
+
export type XmlInstruction = {
|
|
12
|
+
kind: 'processing-instruction';
|
|
13
|
+
target: string;
|
|
14
|
+
value: string;
|
|
15
|
+
};
|
|
16
|
+
export type XmlContent = XmlElement | XmlText | XmlInstruction;
|
|
17
|
+
export type XmlDocument = {
|
|
18
|
+
root: XmlElement;
|
|
19
|
+
prologue: Array<XmlText | XmlInstruction>;
|
|
20
|
+
epilogue: Array<XmlText | XmlInstruction>;
|
|
21
|
+
};
|
|
22
|
+
export declare class XmlDocumentError extends Error {
|
|
23
|
+
readonly code: 'parser-unavailable' | 'unsupported-declaration' | 'malformed-document' | 'parsing-limit';
|
|
24
|
+
constructor(code: 'parser-unavailable' | 'unsupported-declaration' | 'malformed-document' | 'parsing-limit');
|
|
25
|
+
}
|
|
26
|
+
/** No I/O, globals, vendor names, defaults or recovery. Importing this module does not load the grammar.
|
|
27
|
+
* The XML declaration is a processing instruction in the prologue. A leading BOM is refused.
|
|
28
|
+
* Raw DOCTYPE/ENTITY markers refuse even inside comments or CDATA: this conservative preflight is linear.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseDocument(source: string): Promise<XmlDocument>;
|
package/dist/src/xml.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export class XmlDocumentError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(code) {
|
|
4
|
+
super(code === 'parser-unavailable' ? 'Strict XML parser @xmldom/xmldom 0.9.12 is unavailable'
|
|
5
|
+
: code === 'unsupported-declaration' ? 'DTD and entity declarations are unsupported'
|
|
6
|
+
: code === 'parsing-limit' ? 'XML document exceeds the supported parsing limits'
|
|
7
|
+
: 'XML document is not well formed');
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = 'XmlDocumentError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
let grammar;
|
|
13
|
+
function loadGrammar() {
|
|
14
|
+
return grammar ??= import('@xmldom/xmldom').catch(() => { grammar = undefined; throw new XmlDocumentError('parser-unavailable'); });
|
|
15
|
+
}
|
|
16
|
+
/** No I/O, globals, vendor names, defaults or recovery. Importing this module does not load the grammar.
|
|
17
|
+
* The XML declaration is a processing instruction in the prologue. A leading BOM is refused.
|
|
18
|
+
* Raw DOCTYPE/ENTITY markers refuse even inside comments or CDATA: this conservative preflight is linear.
|
|
19
|
+
*/
|
|
20
|
+
export async function parseDocument(source) {
|
|
21
|
+
if (typeof source !== 'string' || source.charCodeAt(0) === 0xfeff)
|
|
22
|
+
throw new XmlDocumentError('malformed-document');
|
|
23
|
+
if (source.indexOf('<!DOCTYPE') !== -1 || source.indexOf('<!ENTITY') !== -1)
|
|
24
|
+
throw new XmlDocumentError('unsupported-declaration');
|
|
25
|
+
const { DOMParser } = await loadGrammar();
|
|
26
|
+
try {
|
|
27
|
+
const document = new DOMParser({ onError: () => { throw new XmlDocumentError('malformed-document'); } }).parseFromString(source, 'application/xml');
|
|
28
|
+
const convert = (node) => {
|
|
29
|
+
if (node.nodeType === 1) {
|
|
30
|
+
const element = node;
|
|
31
|
+
const attributes = Object.create(null);
|
|
32
|
+
for (const attr of Array.from(element.attributes))
|
|
33
|
+
attributes[attr.name] = attr.value;
|
|
34
|
+
return { kind: 'element', name: element.tagName, attributes, content: [] };
|
|
35
|
+
}
|
|
36
|
+
if (node.nodeType === 3 || node.nodeType === 4 || node.nodeType === 8)
|
|
37
|
+
return { kind: node.nodeType === 3 ? 'text' : node.nodeType === 4 ? 'cdata' : 'comment', value: node.nodeValue ?? '' };
|
|
38
|
+
if (node.nodeType === 7)
|
|
39
|
+
return { kind: 'processing-instruction', target: node.nodeName, value: node.nodeValue ?? '' };
|
|
40
|
+
throw new XmlDocumentError(node.nodeType === 10 ? 'unsupported-declaration' : 'malformed-document');
|
|
41
|
+
};
|
|
42
|
+
const pending = [];
|
|
43
|
+
const one = (source) => {
|
|
44
|
+
const target = convert(source);
|
|
45
|
+
if (target.kind === 'element')
|
|
46
|
+
pending.push({ source, target });
|
|
47
|
+
return target;
|
|
48
|
+
};
|
|
49
|
+
const nodes = Array.from(document.childNodes).map(one);
|
|
50
|
+
while (pending.length) {
|
|
51
|
+
const { source, target } = pending.pop();
|
|
52
|
+
for (const child of Array.from(source.childNodes))
|
|
53
|
+
target.content.push(one(child));
|
|
54
|
+
}
|
|
55
|
+
const roots = nodes.filter((node) => node.kind === 'element');
|
|
56
|
+
if (roots.length !== 1)
|
|
57
|
+
throw new XmlDocumentError('malformed-document');
|
|
58
|
+
const root = roots[0], index = nodes.indexOf(root);
|
|
59
|
+
const outside = (list) => list.map(node => {
|
|
60
|
+
if (node.kind === 'element' || node.kind === 'cdata' || (node.kind === 'text' && node.value.trim()))
|
|
61
|
+
throw new XmlDocumentError('malformed-document');
|
|
62
|
+
return node;
|
|
63
|
+
});
|
|
64
|
+
return { root, prologue: outside(nodes.slice(0, index)), epilogue: outside(nodes.slice(index + 1)) };
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error instanceof XmlDocumentError)
|
|
68
|
+
throw error;
|
|
69
|
+
if (error instanceof RangeError)
|
|
70
|
+
throw new XmlDocumentError('parsing-limit');
|
|
71
|
+
// The grammar's diagnostics can contain source bytes. Expose a fixed error, keeping credentials out of reports.
|
|
72
|
+
throw new XmlDocumentError('malformed-document');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -328,6 +328,65 @@
|
|
|
328
328
|
},
|
|
329
329
|
"serveExport": "createClerkTwinServer"
|
|
330
330
|
},
|
|
331
|
+
"clickhouse": {
|
|
332
|
+
"adoption": {
|
|
333
|
+
"sdks": [
|
|
334
|
+
"@clickhouse/client",
|
|
335
|
+
"@clickhouse/client-web"
|
|
336
|
+
],
|
|
337
|
+
"pypi": [
|
|
338
|
+
"clickhouse-driver",
|
|
339
|
+
"clickhouse-connect",
|
|
340
|
+
"infi-clickhouse-orm"
|
|
341
|
+
],
|
|
342
|
+
"envStems": [
|
|
343
|
+
"CLICKHOUSE"
|
|
344
|
+
]
|
|
345
|
+
},
|
|
346
|
+
"hostsNone": "Self-hosted database: its own declared host and allocated listener are supplied by managed infrastructure.",
|
|
347
|
+
"archetype": "crud",
|
|
348
|
+
"protocol": {
|
|
349
|
+
"declared": "3",
|
|
350
|
+
"major": 3,
|
|
351
|
+
"standing": "current"
|
|
352
|
+
},
|
|
353
|
+
"transport": "rest",
|
|
354
|
+
"resources": [
|
|
355
|
+
"database",
|
|
356
|
+
"table",
|
|
357
|
+
"row"
|
|
358
|
+
],
|
|
359
|
+
"endpointEnv": {
|
|
360
|
+
"name": "CLICKHOUSE_URL",
|
|
361
|
+
"note": "HTTP base URL read by the documented JavaScript client."
|
|
362
|
+
},
|
|
363
|
+
"managedService": {
|
|
364
|
+
"kind": "clickhouse",
|
|
365
|
+
"scheme": "http",
|
|
366
|
+
"configurationArg": "--configuration",
|
|
367
|
+
"originalInputs": {
|
|
368
|
+
"version": 1,
|
|
369
|
+
"manifestArg": "--original-inputs",
|
|
370
|
+
"rootArg": "--original-root",
|
|
371
|
+
"digestArg": "--original-inputs-sha256",
|
|
372
|
+
"paths": [
|
|
373
|
+
"/etc/clickhouse-server",
|
|
374
|
+
"/docker-entrypoint-initdb.d",
|
|
375
|
+
"/entrypoint.sh"
|
|
376
|
+
]
|
|
377
|
+
},
|
|
378
|
+
"note": "One HTTP8123/native9000 process and store; declared operator configuration is installed before listeners."
|
|
379
|
+
},
|
|
380
|
+
"sidePorts": [
|
|
381
|
+
{
|
|
382
|
+
"name": "native",
|
|
383
|
+
"option": "nativePort",
|
|
384
|
+
"flag": "--native-port",
|
|
385
|
+
"note": "ClickHouse native TCP protocol, normally9000, beside HTTP8123."
|
|
386
|
+
}
|
|
387
|
+
],
|
|
388
|
+
"serveExport": "createClickhouseTwinServer"
|
|
389
|
+
},
|
|
331
390
|
"cloudflare": {
|
|
332
391
|
"adoption": {
|
|
333
392
|
"pypi": [
|
|
@@ -1011,6 +1070,55 @@
|
|
|
1011
1070
|
"endpointEnvNone": "Google generated clients take rootUrl in code; the World routes the declared Calendar API paths.",
|
|
1012
1071
|
"serveExport": "createGooglecalendarTwinServer"
|
|
1013
1072
|
},
|
|
1073
|
+
"googlefonts": {
|
|
1074
|
+
"adoption": {
|
|
1075
|
+
"sdks": [],
|
|
1076
|
+
"envStems": [
|
|
1077
|
+
"GOOGLE_FONTS"
|
|
1078
|
+
]
|
|
1079
|
+
},
|
|
1080
|
+
"hosts": [
|
|
1081
|
+
{
|
|
1082
|
+
"host": "www.googleapis.com",
|
|
1083
|
+
"pathPattern": "^/webfonts/v1/webfonts$"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
"host": "webfonts.googleapis.com",
|
|
1087
|
+
"pathPattern": "^/v1/webfonts$"
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
"host": "fonts.googleapis.com",
|
|
1091
|
+
"pathPattern": "^/css$"
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
"host": "fonts.gstatic.com",
|
|
1095
|
+
"pathPattern": "^/(s/|l/font$)"
|
|
1096
|
+
}
|
|
1097
|
+
],
|
|
1098
|
+
"archetype": "crud",
|
|
1099
|
+
"protocol": {
|
|
1100
|
+
"declared": "3",
|
|
1101
|
+
"major": 3,
|
|
1102
|
+
"standing": "current"
|
|
1103
|
+
},
|
|
1104
|
+
"transport": "rest",
|
|
1105
|
+
"resources": [
|
|
1106
|
+
"webfont",
|
|
1107
|
+
"_api_key",
|
|
1108
|
+
"_font_catalog",
|
|
1109
|
+
"_stylesheet",
|
|
1110
|
+
"_font_file"
|
|
1111
|
+
],
|
|
1112
|
+
"endpointEnvNone": "Pinned helper hardcodes the vendor API and CSS hosts, then downloads their returned gstatic URLs. Scoped host routing preserves these URLs.",
|
|
1113
|
+
"credentialDoor": {
|
|
1114
|
+
"path": "/_twin/app-credentials",
|
|
1115
|
+
"body": {},
|
|
1116
|
+
"fill": {
|
|
1117
|
+
"GOOGLE_FONTS_API_KEY": "api_key"
|
|
1118
|
+
}
|
|
1119
|
+
},
|
|
1120
|
+
"serveExport": "createGooglefontsTwinServer"
|
|
1121
|
+
},
|
|
1014
1122
|
"googleoauth": {
|
|
1015
1123
|
"adoption": {
|
|
1016
1124
|
"sdks": [
|
|
@@ -1514,6 +1622,38 @@
|
|
|
1514
1622
|
},
|
|
1515
1623
|
"serveExport": "createMistralTwinServer"
|
|
1516
1624
|
},
|
|
1625
|
+
"mongodb": {
|
|
1626
|
+
"adoption": {
|
|
1627
|
+
"sdks": [
|
|
1628
|
+
"mongodb",
|
|
1629
|
+
"mongoose"
|
|
1630
|
+
],
|
|
1631
|
+
"envStems": [
|
|
1632
|
+
"MONGODB",
|
|
1633
|
+
"MONGO"
|
|
1634
|
+
]
|
|
1635
|
+
},
|
|
1636
|
+
"hosts": [],
|
|
1637
|
+
"archetype": "crud",
|
|
1638
|
+
"protocol": {
|
|
1639
|
+
"declared": "3",
|
|
1640
|
+
"major": 3,
|
|
1641
|
+
"standing": "current"
|
|
1642
|
+
},
|
|
1643
|
+
"transport": "raw-tcp",
|
|
1644
|
+
"resources": [
|
|
1645
|
+
"collection",
|
|
1646
|
+
"index",
|
|
1647
|
+
"document"
|
|
1648
|
+
],
|
|
1649
|
+
"endpointEnvNone": "Managed infrastructure injects the connection address from the declared mongodb service; it is a TCP endpoint, with no HTTP API host.",
|
|
1650
|
+
"managedService": {
|
|
1651
|
+
"kind": "mongodb",
|
|
1652
|
+
"scheme": "mongodb",
|
|
1653
|
+
"note": "MongoDB 7.0 wire: standalone, or a declared single-member handshake without sessions; state in the World tree"
|
|
1654
|
+
},
|
|
1655
|
+
"serveExport": "createMongodbTwinServer"
|
|
1656
|
+
},
|
|
1517
1657
|
"npm-registry": {
|
|
1518
1658
|
"adoption": {
|
|
1519
1659
|
"envStems": [
|
package/inject.cjs
CHANGED
|
@@ -146,32 +146,61 @@ function installPrismaAdapterShim() {
|
|
|
146
146
|
if (candidates.length === 0) return;
|
|
147
147
|
Module.__volterPrismaAdapterShimInstalled = true;
|
|
148
148
|
const path = require('path');
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const exports =
|
|
152
|
-
if (
|
|
149
|
+
// The package's own entry (its `main`, `default.js`; `index.js` before Prisma 5), patched as it loads (PACKAGE ENTRIES).
|
|
150
|
+
patchPackageEntry(/[\\/]node_modules[\\/]@prisma[\\/]client[\\/](default|index)\.js$/, (module) => {
|
|
151
|
+
const exports = module.exports;
|
|
152
|
+
if (!exports || typeof exports.PrismaClient !== 'function' || exports.PrismaClient.__volterAdapted) return;
|
|
153
153
|
const vendor = candidates.find((candidate) => MAP[candidate] && process.env[packs[candidate].prismaAdapter.urlEnv]);
|
|
154
|
-
if (!vendor) return
|
|
154
|
+
if (!vendor) return;
|
|
155
155
|
const facts = packs[vendor].prismaAdapter;
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
// THE ADAPTER IS FOUND WHERE THE CLIENT IS USED, AT ITS FIRST CONSTRUCTION WITHOUT ONE (review of the World 2209
|
|
157
|
+
// integration, 75f6a1dd). The entry's own parent is the first module that loaded it. For a copy cached before this
|
|
158
|
+
// prelude ran, that is not the library that later constructs the client, and an early miss there was final.
|
|
159
|
+
// At each construction without an adapter, until one is found, these places are asked in turn:
|
|
160
|
+
// - the directory of each CommonJS module that lists the entry among its children, most recently loaded first, by
|
|
161
|
+
// Module._cache's insertion order, with the entry's module.parent last of them. Node's updateChildren records a
|
|
162
|
+
// cached require too, so a consumer that requires the client later is found at the next construction;
|
|
163
|
+
// - the main module's directory and that of process.argv[1];
|
|
164
|
+
// - the working directory.
|
|
165
|
+
// An ES module that imports the client is never its parent or one of the cached modules that list it, so an ESM
|
|
166
|
+
// consumer is reached only through those last places. A found adapter is kept, and said once if a miss was said
|
|
167
|
+
// before it. A place that missed is not asked again (`missedPlaces`): a new consumer brings a new place, and no
|
|
168
|
+
// resolve is repeated. A miss is said once, and the construction is left as it was. Module._cache is read at each
|
|
169
|
+
// construction without an adapter until one is found, a walk of the cache's entries and no file system work.
|
|
170
|
+
let Adapter;
|
|
171
|
+
let missSaid = false;
|
|
172
|
+
const missedPlaces = new Set();
|
|
173
|
+
const adapterFor = () => {
|
|
174
|
+
if (Adapter) return Adapter;
|
|
175
|
+
const consumers = [module.parent, ...Object.values(Module._cache).filter((other) => other && other !== module.parent && Array.isArray(other.children) && other.children.includes(module))]
|
|
176
|
+
.filter((consumer) => consumer && consumer.filename).reverse();
|
|
177
|
+
// Each place with the module it is asked for, so the adapter loads as that module's child (Node's bookkeeping
|
|
178
|
+
// of parent and children only; resolution is by `paths`).
|
|
179
|
+
const places = new Map();
|
|
180
|
+
for (const consumer of consumers) if (!places.has(path.dirname(consumer.filename))) places.set(path.dirname(consumer.filename), consumer);
|
|
181
|
+
if (require.main && require.main.filename && !places.has(path.dirname(require.main.filename))) places.set(path.dirname(require.main.filename), require.main);
|
|
182
|
+
if (typeof process.argv[1] === 'string' && process.argv[1] && !places.has(path.dirname(path.resolve(process.argv[1])))) places.set(path.dirname(path.resolve(process.argv[1])), null);
|
|
183
|
+
if (!places.has(process.cwd())) places.set(process.cwd(), null);
|
|
184
|
+
let reason = `${facts.adapter} is not installed in this application`;
|
|
185
|
+
for (const [from, consumer] of places) {
|
|
186
|
+
if (missedPlaces.has(from)) continue;
|
|
187
|
+
let loaded;
|
|
188
|
+
try { loaded = Module._load(require.resolve(facts.adapter, { paths: [from] }), consumer, false); }
|
|
189
|
+
catch { missedPlaces.add(from); continue; }
|
|
190
|
+
const found = loaded && loaded[facts.export];
|
|
191
|
+
if (typeof found === 'function') {
|
|
192
|
+
Adapter = found;
|
|
193
|
+
if (missSaid) process.stderr.write(`[twin-inject] ${vendor}: ${facts.adapter} found from ${from}; a Prisma client constructed without an adapter from now on gets it\n`);
|
|
194
|
+
return Adapter;
|
|
195
|
+
}
|
|
196
|
+
missedPlaces.add(from);
|
|
197
|
+
reason = `${facts.adapter} exports no ${facts.export}`;
|
|
198
|
+
}
|
|
163
199
|
// Left as it was, said once: on the client engine Prisma refuses the construction itself;
|
|
164
200
|
// on the library engine the client reaches the twin over the vendor's own wire.
|
|
165
|
-
process.stderr.write(`[twin-inject] ${vendor}: ${
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
const Adapter = adapterModule && adapterModule[facts.export];
|
|
170
|
-
if (typeof Adapter !== 'function') {
|
|
171
|
-
process.stderr.write(`[twin-inject] ${vendor}: ${facts.adapter} exports no ${facts.export}; a Prisma client constructed without an adapter is left as it was\n`);
|
|
172
|
-
exports.PrismaClient.__volterAdapted = true;
|
|
173
|
-
return exports;
|
|
174
|
-
}
|
|
201
|
+
if (!missSaid) { missSaid = true; process.stderr.write(`[twin-inject] ${vendor}: ${reason}, so a Prisma client constructed without an adapter is left as it was until it is found\n`); }
|
|
202
|
+
return undefined;
|
|
203
|
+
};
|
|
175
204
|
const Base = exports.PrismaClient;
|
|
176
205
|
class PrismaClient extends Base {
|
|
177
206
|
constructor(options) {
|
|
@@ -180,16 +209,18 @@ function installPrismaAdapterShim() {
|
|
|
180
209
|
// decision. The URL is the application's where it names one (its host is twinned by the
|
|
181
210
|
// injector's own host rules), else the endpoint template's variable.
|
|
182
211
|
if ('adapter' in given) { super(given); return; }
|
|
212
|
+
const Found = adapterFor();
|
|
213
|
+
// Left as it was: Prisma is given exactly what the application passed (`new PrismaClient()` is no options).
|
|
214
|
+
if (!Found) { super(...arguments); return; }
|
|
183
215
|
const named = given.datasources && typeof given.datasources === 'object'
|
|
184
216
|
? Object.values(given.datasources).map((source) => source && source.url).find((value) => typeof value === 'string') : undefined;
|
|
185
217
|
const url = given.datasourceUrl || named || process.env[facts.urlEnv];
|
|
186
|
-
super({ ...given, adapter: new
|
|
218
|
+
super({ ...given, adapter: new Found({ url, fetch: (...args) => globalThis.fetch(...args) }) });
|
|
187
219
|
}
|
|
188
220
|
}
|
|
189
221
|
PrismaClient.__volterAdapted = true;
|
|
190
222
|
exports.PrismaClient = PrismaClient;
|
|
191
|
-
|
|
192
|
-
};
|
|
223
|
+
});
|
|
193
224
|
}
|
|
194
225
|
|
|
195
226
|
// The exact inverse of readMap's env lookup: which vendor (if any) would the injector read
|
|
@@ -647,50 +678,77 @@ function routedTwin(url) {
|
|
|
647
678
|
}
|
|
648
679
|
// Imported Undici APIs may hold a dispatcher obtained before the global view was installed.
|
|
649
680
|
// Rewrite their public HTTP doors as well; an independent connector still faces the socket guards.
|
|
650
|
-
|
|
681
|
+
// PACKAGE ENTRIES, TAKEN WHEN THEY LOAD (S2): the preludes that act on one package (undici, @prisma/client, miniflare)
|
|
682
|
+
// wrapped Module._load and ran on every load of the process to compare one name (LibreChat's server: 20,228 loads,
|
|
683
|
+
// ~20 ms in the tab, none of it in native's path), and a wrapped Module._load kept the tab's engine on its slower
|
|
684
|
+
// replaced-load route for every require. Each is now a patch of the package's entry module, made when that file is
|
|
685
|
+
// loaded (Module._extensions['.js'], once per new module): the entry is loaded once per copy (every version, every
|
|
686
|
+
// root, late or early) and cached, so the exports the patch leaves are what every later require of that copy is
|
|
687
|
+
// answered, and an `import` of it loads it the same way. A copy loaded before this prelude ran is patched where it is
|
|
688
|
+
// cached: its exports object is patched in place, so later requires and imports, and a module that holds that exports
|
|
689
|
+
// object, see the patch; only a binding taken from it before the prelude ran (a destructured PrismaClient, an ES
|
|
690
|
+
// module's namespace already linked) keeps the original. Known limits: a '.js' handler installed later that does not call the one it replaced hides the entries
|
|
691
|
+
// loaded through it; an entry outside a node_modules directory (a linked checkout of the package) is not recognized.
|
|
692
|
+
const ENTRY_PATCHES = [];
|
|
693
|
+
let ENTRY_LOAD = null;
|
|
694
|
+
function patchPackageEntry(pattern, patch) {
|
|
695
|
+
ENTRY_PATCHES.push({ pattern, patch });
|
|
696
|
+
for (const [filename, module] of Object.entries(Module._cache)) {
|
|
697
|
+
if (pattern.test(filename) && module && module.loaded) patch(module, filename);
|
|
698
|
+
}
|
|
699
|
+
if (ENTRY_LOAD) return;
|
|
700
|
+
const original = ENTRY_LOAD = Module._extensions['.js'];
|
|
701
|
+
Module._extensions['.js'] = function volterPackageEntry(module, filename) {
|
|
702
|
+
const result = original.apply(this, arguments);
|
|
703
|
+
for (const entry of ENTRY_PATCHES) if (entry.pattern.test(filename)) entry.patch(module, filename);
|
|
704
|
+
return result;
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
let UNDICI_ROUTED = false;
|
|
651
709
|
function routeImportedUndici() {
|
|
652
|
-
if (
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
options.headers = Array.from(input.headers);
|
|
673
|
-
if (input.body !== null && input.body !== undefined) { options.body = input.body; options.duplex = 'half'; }
|
|
674
|
-
return globalThis.fetch(input.url, { ...options, ...init });
|
|
710
|
+
if (UNDICI_ROUTED) return;
|
|
711
|
+
UNDICI_ROUTED = true;
|
|
712
|
+
patchPackageEntry(/[\\/]node_modules[\\/]undici[\\/]index\.js$/, (module) => {
|
|
713
|
+
if (module.exports && typeof module.exports.request === 'function' && !ROUTED_UNDICI.has(module.exports)) module.exports = routedUndici(module.exports);
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
const ROUTED_UNDICI = new WeakSet();
|
|
717
|
+
function routedUndici(exports) {
|
|
718
|
+
const view = Object.assign({}, exports);
|
|
719
|
+
view.fetch = function routedUndiciFetch(input, init) {
|
|
720
|
+
if (!installed) return exports.fetch(input, init);
|
|
721
|
+
let url; try { url = new URL(typeof input === 'object' && input?.url ? input.url : String(input)); } catch {}
|
|
722
|
+
const twin = routedTwin(url);
|
|
723
|
+
// Local control planes may use their own Request class and dispatcher. Preserve both;
|
|
724
|
+
// connections still pass the socket guards, and claimed vendor hops still enter routing.
|
|
725
|
+
if (url && isLocalOrPrivateHost(url.hostname) && (!twin || twin.vendor === 'app')) return exports.fetch(input, init);
|
|
726
|
+
if (input && typeof input === 'object' && typeof input.url === 'string' && !(input instanceof globalThis.Request)) {
|
|
727
|
+
const options = {};
|
|
728
|
+
for (const name of ['method', 'signal', 'redirect', 'cache', 'credentials', 'integrity', 'keepalive', 'referrer', 'referrerPolicy']) {
|
|
729
|
+
if (input[name] !== undefined) options[name] = input[name];
|
|
675
730
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
731
|
+
options.headers = Array.from(input.headers);
|
|
732
|
+
if (input.body !== null && input.body !== undefined) { options.body = input.body; options.duplex = 'half'; }
|
|
733
|
+
return globalThis.fetch(input.url, { ...options, ...init });
|
|
734
|
+
}
|
|
735
|
+
return globalThis.fetch(input, init);
|
|
736
|
+
};
|
|
737
|
+
view.request = function routedUndiciRequest(input, options, callback) {
|
|
738
|
+
if (!installed) return exports.request.apply(exports, arguments);
|
|
739
|
+
const opts = typeof options === 'function' ? {} : options ?? {};
|
|
740
|
+
let url; try { url = new URL(String(input)); if (opts.path !== undefined) url = new URL(url.origin + String(opts.path)); } catch {}
|
|
741
|
+
const twin = routedTwin(url);
|
|
742
|
+
if (!twin || twin.vendor === 'app') return exports.request.apply(exports, arguments);
|
|
743
|
+
const headers = undiciHeaderObject(opts.headers);
|
|
744
|
+
headers.host = url.host; headers['x-volter-twin-original-host'] = url.host;
|
|
745
|
+
const key = twinsKey(); if (key) headers['x-twins-key'] = key;
|
|
746
|
+
const target = twin.origin.replace(/\/$/, '') + url.pathname + url.search;
|
|
747
|
+
const { path: _path, ...requestOptions } = opts; // target already carries the effective path and endpoint prefix
|
|
748
|
+
return exports.request(target, { ...requestOptions, headers, maxRedirections: 0 }, typeof options === 'function' ? options : callback);
|
|
693
749
|
};
|
|
750
|
+
ROUTED_UNDICI.add(view);
|
|
751
|
+
return view;
|
|
694
752
|
}
|
|
695
753
|
function unkeyUndiciDispatches() {
|
|
696
754
|
if (!ORIGINAL_DEFINE_PROPERTY) return;
|
|
@@ -1712,12 +1770,25 @@ function installWorldTime() {
|
|
|
1712
1770
|
const worldMs = () => { const c = clock(); return c ? clockNowMs(c, machineNow()) : machineNow(); };
|
|
1713
1771
|
// the machine's own Date, wrapped rather than subclassed, so identity holds everywhere: dates Node makes itself
|
|
1714
1772
|
// (a file's mtime, structuredClone, a worker's message) are `instanceof Date`, `d.constructor === Date` stays true,
|
|
1715
|
-
// and Date.prototype is the machine's; only now() and argument-less construction read the World's time
|
|
1716
|
-
|
|
1717
|
-
|
|
1773
|
+
// and Date.prototype is the machine's; only now() and argument-less construction read the World's time. A bound
|
|
1774
|
+
// function, not a Proxy: every `new Date(x)` of the app (a driver decoding dates) ran the Proxy's construct trap,
|
|
1775
|
+
// ~15 ms of self time on LibreChat's server start in the tab (S2). Bound, so Function.prototype.toString of Date
|
|
1776
|
+
// says "function () { [native code] }", as the Proxy's did; a bound function constructs its target with the target
|
|
1777
|
+
// as new.target, and a subclass's own new.target passes through. Its prototype is the machine's; its own keys are
|
|
1778
|
+
// the machine's Date's (length, name, prototype, now, parse, UTC), `now` the World's.
|
|
1779
|
+
const worldDate = function Date(...args) {
|
|
1718
1780
|
// called as a function, Date() answers the current time's string, as the machine's does
|
|
1719
|
-
|
|
1720
|
-
|
|
1781
|
+
if (new.target === undefined) return new MachineDate(worldMs()).toString();
|
|
1782
|
+
return Reflect.construct(MachineDate, args.length ? args : [worldMs()], new.target === worldDate ? MachineDate : new.target);
|
|
1783
|
+
};
|
|
1784
|
+
worldDate.prototype = MachineDate.prototype;
|
|
1785
|
+
const WorldDate = worldDate.bind(undefined);
|
|
1786
|
+
Object.defineProperty(WorldDate, 'name', { value: 'Date', configurable: true });
|
|
1787
|
+
Object.defineProperty(WorldDate, 'length', { value: MachineDate.length, configurable: true });
|
|
1788
|
+
Object.defineProperty(WorldDate, 'prototype', { value: MachineDate.prototype });
|
|
1789
|
+
for (const [key, value] of [['now', worldMs], ['parse', MachineDate.parse], ['UTC', MachineDate.UTC]]) {
|
|
1790
|
+
Object.defineProperty(WorldDate, key, { value, writable: true, configurable: true, enumerable: false });
|
|
1791
|
+
}
|
|
1721
1792
|
Object.defineProperty(globalThis, Symbol.for('volter.machineDateNow'), { value: machineNow, enumerable: false });
|
|
1722
1793
|
MachineDate.now = worldMs;
|
|
1723
1794
|
Object.defineProperty(MachineDate.prototype, 'constructor', { value: WorldDate, writable: true, configurable: true, enumerable: false });
|
|
@@ -1780,17 +1851,12 @@ function installMiniflareOutbound() {
|
|
|
1780
1851
|
};
|
|
1781
1852
|
return Array.isArray(options.workers) ? { ...options, workers: options.workers.map(worker) } : worker(options);
|
|
1782
1853
|
};
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
if (
|
|
1789
|
-
if (!outbound) {
|
|
1790
|
-
let at = null;
|
|
1791
|
-
try { at = Module._resolveFilename(request, parent); } catch { at = null; }
|
|
1792
|
-
outbound = outboundFor(at, exports.fetch);
|
|
1793
|
-
}
|
|
1854
|
+
// The package's own entry (miniflare's `main`, dist/src/index.js), patched as it loads (PACKAGE ENTRIES).
|
|
1855
|
+
patchPackageEntry(/[\\/]node_modules[\\/]miniflare[\\/]dist[\\/]src[\\/]index\.js$/, (module, filename) => {
|
|
1856
|
+
const exports = module.exports;
|
|
1857
|
+
if (!exports || typeof exports.Miniflare !== 'function' || exports.Miniflare.__volterRouted) return;
|
|
1858
|
+
// the entry is the file `require('miniflare')` resolved to: its undici is the one beside it
|
|
1859
|
+
if (!outbound) outbound = outboundFor(filename, exports.fetch);
|
|
1794
1860
|
const Original = exports.Miniflare;
|
|
1795
1861
|
class Miniflare extends Original {
|
|
1796
1862
|
constructor(options) { super(routed(options)); }
|
|
@@ -1799,10 +1865,8 @@ function installMiniflareOutbound() {
|
|
|
1799
1865
|
Miniflare.__volterRouted = true;
|
|
1800
1866
|
// miniflare's build exports `Miniflare` as a getter that can be neither assigned nor redefined: its importer is given
|
|
1801
1867
|
// a view of the module whose `Miniflare` is this one, the same view each time it is required.
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
return view;
|
|
1805
|
-
};
|
|
1868
|
+
module.exports = new Proxy(exports, { get: (target, key, receiver) => (key === 'Miniflare' ? Miniflare : Reflect.get(target, key, receiver)) });
|
|
1869
|
+
});
|
|
1806
1870
|
}
|
|
1807
1871
|
|
|
1808
1872
|
// Auto-install as a preload (`--require`); strict refusal also applies without twin URLs.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.156",
|
|
4
4
|
"description": "The kernel of Volter World: one log per twin, branches as pointers, checkpoints, the fold that keeps a twin current, the head that performs a write against the vendor, references, and the git plane. A twin package builds on it; the runtime serves it.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
|
@@ -128,9 +128,25 @@
|
|
|
128
128
|
"types": "./dist/src/live/index.d.ts",
|
|
129
129
|
"default": "./dist/src/live/index.js"
|
|
130
130
|
},
|
|
131
|
+
"./mongodb": {
|
|
132
|
+
"types": "./dist/src/mongodb/index.d.ts",
|
|
133
|
+
"default": "./dist/src/mongodb/index.js"
|
|
134
|
+
},
|
|
131
135
|
"./clickhouse": {
|
|
132
136
|
"types": "./dist/src/clickhouse/index.d.ts",
|
|
133
137
|
"default": "./dist/src/clickhouse/index.js"
|
|
138
|
+
},
|
|
139
|
+
"./runtime-state": {
|
|
140
|
+
"types": "./dist/src/runtime-state.d.ts",
|
|
141
|
+
"default": "./dist/src/runtime-state.js"
|
|
142
|
+
},
|
|
143
|
+
"./browser-state": {
|
|
144
|
+
"types": "./dist/src/browser-state.d.ts",
|
|
145
|
+
"default": "./dist/src/browser-state.js"
|
|
146
|
+
},
|
|
147
|
+
"./managed-original-inputs": {
|
|
148
|
+
"types": "./dist/src/managed-original-inputs.d.ts",
|
|
149
|
+
"default": "./dist/src/managed-original-inputs.js"
|
|
134
150
|
}
|
|
135
151
|
},
|
|
136
152
|
"scripts": {
|
|
@@ -156,5 +172,8 @@
|
|
|
156
172
|
},
|
|
157
173
|
"engines": {
|
|
158
174
|
"node": ">=22.3"
|
|
175
|
+
},
|
|
176
|
+
"optionalDependencies": {
|
|
177
|
+
"@xmldom/xmldom": "0.9.12"
|
|
159
178
|
}
|
|
160
179
|
}
|