@volter/world-core 3.0.154 → 3.0.155
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 +12 -3
- package/dist/src/client-bundle.js +15 -15
- package/dist/src/graphql-wire.d.ts +5 -0
- package/dist/src/graphql-wire.js +6 -6
- package/dist/src/pack-fetch.d.ts +2 -1
- package/dist/src/pack-fetch.js +1 -1
- package/generated/pack-facts.json +12 -3
- package/package.json +1 -1
- package/src/client-bundle.ts +13 -14
- package/src/graphql-wire.ts +9 -6
- package/src/pack-fetch.ts +3 -3
|
@@ -270,6 +270,9 @@
|
|
|
270
270
|
{
|
|
271
271
|
"host": "api.clerk.com"
|
|
272
272
|
},
|
|
273
|
+
{
|
|
274
|
+
"host": "dashboard.clerk.com"
|
|
275
|
+
},
|
|
273
276
|
{
|
|
274
277
|
"suffix": ".clerk.accounts.dev"
|
|
275
278
|
},
|
|
@@ -1309,8 +1312,7 @@
|
|
|
1309
1312
|
"host": "api.linear.app"
|
|
1310
1313
|
},
|
|
1311
1314
|
{
|
|
1312
|
-
"host": "linear.app"
|
|
1313
|
-
"pathPattern": "^/oauth/"
|
|
1315
|
+
"host": "linear.app"
|
|
1314
1316
|
}
|
|
1315
1317
|
],
|
|
1316
1318
|
"archetype": "crud",
|
|
@@ -1330,7 +1332,7 @@
|
|
|
1330
1332
|
"comment",
|
|
1331
1333
|
"issue_label"
|
|
1332
1334
|
],
|
|
1333
|
-
"endpointEnvNone": "Linear uses api.linear.app/graphql and linear.app
|
|
1335
|
+
"endpointEnvNone": "Linear uses api.linear.app/graphql and linear.app for its workspace and OAuth authorize page; the World claims those hosts",
|
|
1334
1336
|
"credentialDoor": {
|
|
1335
1337
|
"path": "/_twin/local-credentials",
|
|
1336
1338
|
"body": {},
|
|
@@ -2023,6 +2025,10 @@
|
|
|
2023
2025
|
},
|
|
2024
2026
|
{
|
|
2025
2027
|
"host": "inbound-cdn.resend.com"
|
|
2028
|
+
},
|
|
2029
|
+
{
|
|
2030
|
+
"host": "resend.com",
|
|
2031
|
+
"pathPattern": "^/emails(?:/|$)"
|
|
2026
2032
|
}
|
|
2027
2033
|
],
|
|
2028
2034
|
"archetype": "crud",
|
|
@@ -2179,6 +2185,9 @@
|
|
|
2179
2185
|
]
|
|
2180
2186
|
},
|
|
2181
2187
|
"hosts": [
|
|
2188
|
+
{
|
|
2189
|
+
"host": "app.slack.com"
|
|
2190
|
+
},
|
|
2182
2191
|
{
|
|
2183
2192
|
"host": "slack.com"
|
|
2184
2193
|
},
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// A page's browser client from its `client/<name>.tsx` entry (the console's, the platform's), runtime-neutral (the
|
|
2
|
-
// serve seam's helpers, docs/contributing/architecture.md#the-serve-seam):
|
|
3
|
-
// by scripts/publish/build.mjs into dist/client/.
|
|
4
|
-
//
|
|
2
|
+
// serve seam's helpers, docs/contributing/architecture.md#the-serve-seam): serve an adjacent `<name>.bundle.js`
|
|
3
|
+
// under either runtime, written at pack time by scripts/publish/build.mjs into dist/client/. Without one, Bun
|
|
4
|
+
// builds the source at serve time and Node refuses it. Kept once per process; a failed attempt is retried on
|
|
5
|
+
// the next call. Nothing here runs at module scope.
|
|
5
6
|
import { existsSync, readFileSync } from 'node:fs';
|
|
6
7
|
/** A file URL's path on this machine, without `node:url` (the modules that call it ride into browser
|
|
7
8
|
* bundles): percent-escapes decoded, and without the slash `URL.pathname` puts before a Windows drive
|
|
@@ -18,19 +19,18 @@ const PROCESS_SHIM = 'globalThis.process=globalThis.process||{env:{NODE_ENV:"pro
|
|
|
18
19
|
export function bundleClient(entry) {
|
|
19
20
|
let pending = bundles.get(entry);
|
|
20
21
|
if (!pending) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!result.success)
|
|
25
|
-
throw new Error(result.logs.map((l) => l.message).join('\n') || `client build failed: ${entry}`);
|
|
26
|
-
return PROCESS_SHIM + await result.outputs[0].text();
|
|
27
|
-
})
|
|
28
|
-
: Promise.resolve().then(() => {
|
|
29
|
-
const prebuilt = entry.replace(/\.tsx?$/, '.bundle.js');
|
|
30
|
-
if (!existsSync(prebuilt))
|
|
31
|
-
throw new Error(`client bundle missing at ${prebuilt} — the package's \`build\` writes it (scripts/publish/build.mjs); Node serves the prebuilt client`);
|
|
22
|
+
pending = Promise.resolve().then(async () => {
|
|
23
|
+
const prebuilt = entry.replace(/\.tsx?$/, '.bundle.js');
|
|
24
|
+
if (existsSync(prebuilt))
|
|
32
25
|
return PROCESS_SHIM + readFileSync(prebuilt, 'utf8');
|
|
33
|
-
|
|
26
|
+
const bun = globalThis.Bun;
|
|
27
|
+
if (!bun || typeof bun.build !== 'function')
|
|
28
|
+
throw new Error(`client bundle missing at ${prebuilt} — the package's \`build\` writes it (scripts/publish/build.mjs); Node serves the prebuilt client`);
|
|
29
|
+
const result = await bun.build({ entrypoints: [entry], target: 'browser', minify: true });
|
|
30
|
+
if (!result.success)
|
|
31
|
+
throw new Error(result.logs.map((l) => l.message).join('\n') || `client build failed: ${entry}`);
|
|
32
|
+
return PROCESS_SHIM + await result.outputs[0].text();
|
|
33
|
+
})
|
|
34
34
|
.catch((error) => { bundles.delete(entry); throw error; });
|
|
35
35
|
bundles.set(entry, pending);
|
|
36
36
|
}
|
|
@@ -20,12 +20,16 @@ export declare class GraphqlError extends Error {
|
|
|
20
20
|
readonly type?: string | undefined;
|
|
21
21
|
constructor(message: string, type?: string | undefined);
|
|
22
22
|
}
|
|
23
|
+
type GraphqlLib = typeof import('graphql');
|
|
24
|
+
export type GraphqlLibraryLoader = () => Promise<GraphqlLib>;
|
|
23
25
|
/** A GraphQL endpoint over a schema and a pack's part: answers a request's `{query, variables, operationName}`. The
|
|
24
26
|
* context each resolver receives is made per request (the handler context). `unmodeled` answers a query selecting a
|
|
25
27
|
* field nothing models; `mutationRefused`, when given, a mutation the World may not make (a read-only twin). */
|
|
26
28
|
export declare function graphqlEndpoint<C>(options: {
|
|
27
29
|
sdl: string;
|
|
28
30
|
part: GraphqlPart<C>;
|
|
31
|
+
/** The generated pack fetch's lazy import, resolving the library from the pack that declares it. */
|
|
32
|
+
loadLibrary?: GraphqlLibraryLoader;
|
|
29
33
|
context: (request: Request) => Promise<C>;
|
|
30
34
|
unmodeled: (field: {
|
|
31
35
|
type: string;
|
|
@@ -33,3 +37,4 @@ export declare function graphqlEndpoint<C>(options: {
|
|
|
33
37
|
}) => Response;
|
|
34
38
|
mutationRefused?: (request: Request) => Response | undefined;
|
|
35
39
|
}): (request: Request) => Promise<Response>;
|
|
40
|
+
export {};
|
package/dist/src/graphql-wire.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
// modeled; any other is answered by the manifest's `graphql.unmodeled`, naming the first field nothing models. An error
|
|
8
8
|
// a resolver throws (`GraphqlError`) carries its `type`, as GitHub's GraphQL errors do.
|
|
9
9
|
//
|
|
10
|
-
// The
|
|
11
|
-
//
|
|
12
|
-
// loads nothing.
|
|
10
|
+
// The generated pack fetch supplies a lazy pack-local loader for the `graphql` protocol library installed by the pack's
|
|
11
|
+
// package.json. Each endpoint caches its library on the first request; callers without a loader keep the kernel-relative
|
|
12
|
+
// lazy import fallback. The kernel's own dependencies stay B1's, and importing the kernel loads nothing.
|
|
13
13
|
/** An error a resolver answers, with the vendor's `type` for it (GitHub's NOT_FOUND, UNPROCESSABLE). */
|
|
14
14
|
export class GraphqlError extends Error {
|
|
15
15
|
type;
|
|
@@ -19,8 +19,6 @@ export class GraphqlError extends Error {
|
|
|
19
19
|
this.name = 'GraphqlError';
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
let lib;
|
|
23
|
-
const graphqlLib = () => (lib ??= import('graphql'));
|
|
24
22
|
const snake = (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
25
23
|
/** A list as a Relay connection, paged by `first`/`last` and `after`. */
|
|
26
24
|
function connection(items, args) {
|
|
@@ -43,6 +41,8 @@ function connection(items, args) {
|
|
|
43
41
|
* context each resolver receives is made per request (the handler context). `unmodeled` answers a query selecting a
|
|
44
42
|
* field nothing models; `mutationRefused`, when given, a mutation the World may not make (a read-only twin). */
|
|
45
43
|
export function graphqlEndpoint(options) {
|
|
44
|
+
let lib;
|
|
45
|
+
const loadLibrary = options.loadLibrary ?? (() => import('graphql'));
|
|
46
46
|
let schema;
|
|
47
47
|
const { resolvers, aliases, stored } = options.part;
|
|
48
48
|
// introspection (`__typename`, `__type`, `__schema` and the `__Type`/`__Field`/… meta types) is the vendor's schema
|
|
@@ -50,7 +50,7 @@ export function graphqlEndpoint(options) {
|
|
|
50
50
|
// before it merges)
|
|
51
51
|
const modeled = (type, field) => field.startsWith('__') || type.startsWith('__') || `${type}.${field}` in resolvers || !!aliases?.[type]?.[field] || !!stored?.[type]?.includes(field) || !!stored?.[type]?.includes(snake(field));
|
|
52
52
|
return async (request) => {
|
|
53
|
-
const g = await
|
|
53
|
+
const g = await (lib ??= loadLibrary());
|
|
54
54
|
schema ??= g.buildSchema(options.sdl, { assumeValidSDL: true });
|
|
55
55
|
const payload = (await request.clone().json().catch(() => ({})));
|
|
56
56
|
let document;
|
package/dist/src/pack-fetch.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ApplicationStandIn } from './events.js';
|
|
|
5
5
|
import { type SocketEngine } from './sockets.js';
|
|
6
6
|
import type { LiveEngine } from './live/types.js';
|
|
7
7
|
import type { WebSocketUpgrade } from './serve-http.js';
|
|
8
|
-
import { type GraphqlPart } from './graphql-wire.js';
|
|
8
|
+
import { type GraphqlPart, type GraphqlLibraryLoader } from './graphql-wire.js';
|
|
9
9
|
/** What a pack declares and writes, and nothing it assembles itself. */
|
|
10
10
|
export type PackParts = {
|
|
11
11
|
manifest: DerivedManifest;
|
|
@@ -39,6 +39,7 @@ export type PackParts = {
|
|
|
39
39
|
* state, served at the manifest's `graphql.paths` (graphql-wire.ts). */
|
|
40
40
|
graphql?: GraphqlPart<HandlerContext> & {
|
|
41
41
|
sdl: string;
|
|
42
|
+
loadLibrary?: GraphqlLibraryLoader;
|
|
42
43
|
};
|
|
43
44
|
/** `semantics/sockets.ts`: each socket's engine, by the id the manifest's `sockets` gives it (sockets.ts). */
|
|
44
45
|
sockets?: Record<string, SocketEngine<HandlerContext>>;
|
package/dist/src/pack-fetch.js
CHANGED
|
@@ -160,7 +160,7 @@ export function createPackFetch(parts, options = {}) {
|
|
|
160
160
|
// the GraphQL wire over the same state, at the paths the manifest names (graphql-wire.ts)
|
|
161
161
|
const gql = m.graphql && parts.graphql ? m.graphql : undefined;
|
|
162
162
|
const graphql = gql && parts.graphql ? graphqlEndpoint({
|
|
163
|
-
sdl: parts.graphql.sdl, part: parts.graphql,
|
|
163
|
+
sdl: parts.graphql.sdl, part: parts.graphql, loadLibrary: parts.graphql.loadLibrary,
|
|
164
164
|
context: async (request) => contextFor(m, { request: request.clone(), operation: { id: 'graphql', method: 'POST', path: gql.paths[0], class: 'action' }, params: {} }, scope),
|
|
165
165
|
unmodeled: ({ type, field }) => Response.json({ errors: [{ ...(gql.unmodeled.type ? { type: gql.unmodeled.type } : {}), message: gql.unmodeled.message.replace('{field}', field).replace('{type}', type) }] }, { status: gql.unmodeled.status ?? 200 }),
|
|
166
166
|
mutationRefused: (request) => ((options.readOnly ?? false) || isReadOnlyRequest(request) ? vendorError(m, m.readOnly) : undefined),
|
|
@@ -270,6 +270,9 @@
|
|
|
270
270
|
{
|
|
271
271
|
"host": "api.clerk.com"
|
|
272
272
|
},
|
|
273
|
+
{
|
|
274
|
+
"host": "dashboard.clerk.com"
|
|
275
|
+
},
|
|
273
276
|
{
|
|
274
277
|
"suffix": ".clerk.accounts.dev"
|
|
275
278
|
},
|
|
@@ -1309,8 +1312,7 @@
|
|
|
1309
1312
|
"host": "api.linear.app"
|
|
1310
1313
|
},
|
|
1311
1314
|
{
|
|
1312
|
-
"host": "linear.app"
|
|
1313
|
-
"pathPattern": "^/oauth/"
|
|
1315
|
+
"host": "linear.app"
|
|
1314
1316
|
}
|
|
1315
1317
|
],
|
|
1316
1318
|
"archetype": "crud",
|
|
@@ -1330,7 +1332,7 @@
|
|
|
1330
1332
|
"comment",
|
|
1331
1333
|
"issue_label"
|
|
1332
1334
|
],
|
|
1333
|
-
"endpointEnvNone": "Linear uses api.linear.app/graphql and linear.app
|
|
1335
|
+
"endpointEnvNone": "Linear uses api.linear.app/graphql and linear.app for its workspace and OAuth authorize page; the World claims those hosts",
|
|
1334
1336
|
"credentialDoor": {
|
|
1335
1337
|
"path": "/_twin/local-credentials",
|
|
1336
1338
|
"body": {},
|
|
@@ -2023,6 +2025,10 @@
|
|
|
2023
2025
|
},
|
|
2024
2026
|
{
|
|
2025
2027
|
"host": "inbound-cdn.resend.com"
|
|
2028
|
+
},
|
|
2029
|
+
{
|
|
2030
|
+
"host": "resend.com",
|
|
2031
|
+
"pathPattern": "^/emails(?:/|$)"
|
|
2026
2032
|
}
|
|
2027
2033
|
],
|
|
2028
2034
|
"archetype": "crud",
|
|
@@ -2179,6 +2185,9 @@
|
|
|
2179
2185
|
]
|
|
2180
2186
|
},
|
|
2181
2187
|
"hosts": [
|
|
2188
|
+
{
|
|
2189
|
+
"host": "app.slack.com"
|
|
2190
|
+
},
|
|
2182
2191
|
{
|
|
2183
2192
|
"host": "slack.com"
|
|
2184
2193
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.155",
|
|
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",
|
package/src/client-bundle.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// A page's browser client from its `client/<name>.tsx` entry (the console's, the platform's), runtime-neutral (the
|
|
2
|
-
// serve seam's helpers, docs/contributing/architecture.md#the-serve-seam):
|
|
3
|
-
// by scripts/publish/build.mjs into dist/client/.
|
|
4
|
-
//
|
|
2
|
+
// serve seam's helpers, docs/contributing/architecture.md#the-serve-seam): serve an adjacent `<name>.bundle.js`
|
|
3
|
+
// under either runtime, written at pack time by scripts/publish/build.mjs into dist/client/. Without one, Bun
|
|
4
|
+
// builds the source at serve time and Node refuses it. Kept once per process; a failed attempt is retried on
|
|
5
|
+
// the next call. Nothing here runs at module scope.
|
|
5
6
|
import { existsSync, readFileSync } from 'node:fs';
|
|
6
7
|
|
|
7
8
|
/** A file URL's path on this machine, without `node:url` (the modules that call it ride into browser
|
|
@@ -23,17 +24,15 @@ const PROCESS_SHIM = 'globalThis.process=globalThis.process||{env:{NODE_ENV:"pro
|
|
|
23
24
|
export function bundleClient(entry: string): Promise<string> {
|
|
24
25
|
let pending = bundles.get(entry);
|
|
25
26
|
if (!pending) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return PROCESS_SHIM + readFileSync(prebuilt, 'utf8');
|
|
36
|
-
}))
|
|
27
|
+
pending = Promise.resolve().then(async () => {
|
|
28
|
+
const prebuilt = entry.replace(/\.tsx?$/, '.bundle.js');
|
|
29
|
+
if (existsSync(prebuilt)) return PROCESS_SHIM + readFileSync(prebuilt, 'utf8');
|
|
30
|
+
const bun = (globalThis as { Bun?: Partial<BunBuild> }).Bun;
|
|
31
|
+
if (!bun || typeof bun.build !== 'function') throw new Error(`client bundle missing at ${prebuilt} — the package's \`build\` writes it (scripts/publish/build.mjs); Node serves the prebuilt client`);
|
|
32
|
+
const result = await (bun as BunBuild).build({ entrypoints: [entry], target: 'browser', minify: true });
|
|
33
|
+
if (!result.success) throw new Error(result.logs.map((l) => l.message).join('\n') || `client build failed: ${entry}`);
|
|
34
|
+
return PROCESS_SHIM + await result.outputs[0]!.text();
|
|
35
|
+
})
|
|
37
36
|
.catch((error) => { bundles.delete(entry); throw error; });
|
|
38
37
|
bundles.set(entry, pending);
|
|
39
38
|
}
|
package/src/graphql-wire.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
// modeled; any other is answered by the manifest's `graphql.unmodeled`, naming the first field nothing models. An error
|
|
8
8
|
// a resolver throws (`GraphqlError`) carries its `type`, as GitHub's GraphQL errors do.
|
|
9
9
|
//
|
|
10
|
-
// The
|
|
11
|
-
//
|
|
12
|
-
// loads nothing.
|
|
10
|
+
// The generated pack fetch supplies a lazy pack-local loader for the `graphql` protocol library installed by the pack's
|
|
11
|
+
// package.json. Each endpoint caches its library on the first request; callers without a loader keep the kernel-relative
|
|
12
|
+
// lazy import fallback. The kernel's own dependencies stay B1's, and importing the kernel loads nothing.
|
|
13
13
|
|
|
14
14
|
/** A resolver of one field, `Type.field`: its parent object, its arguments, and the request's handler context. */
|
|
15
15
|
export type GraphqlResolver<C = unknown> = (source: Record<string, unknown>, args: Record<string, unknown>, ctx: C) => unknown;
|
|
@@ -32,8 +32,7 @@ export class GraphqlError extends Error {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
type GraphqlLib = typeof import('graphql');
|
|
35
|
-
|
|
36
|
-
const graphqlLib = (): Promise<GraphqlLib> => (lib ??= import('graphql') as Promise<GraphqlLib>);
|
|
35
|
+
export type GraphqlLibraryLoader = () => Promise<GraphqlLib>;
|
|
37
36
|
|
|
38
37
|
const snake = (s: string): string => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
39
38
|
|
|
@@ -59,10 +58,14 @@ function connection(items: unknown[], args: Record<string, unknown>): Record<str
|
|
|
59
58
|
export function graphqlEndpoint<C>(options: {
|
|
60
59
|
sdl: string;
|
|
61
60
|
part: GraphqlPart<C>;
|
|
61
|
+
/** The generated pack fetch's lazy import, resolving the library from the pack that declares it. */
|
|
62
|
+
loadLibrary?: GraphqlLibraryLoader;
|
|
62
63
|
context: (request: Request) => Promise<C>;
|
|
63
64
|
unmodeled: (field: { type: string; field: string }) => Response;
|
|
64
65
|
mutationRefused?: (request: Request) => Response | undefined;
|
|
65
66
|
}): (request: Request) => Promise<Response> {
|
|
67
|
+
let lib: Promise<GraphqlLib> | undefined;
|
|
68
|
+
const loadLibrary = options.loadLibrary ?? (() => import('graphql'));
|
|
66
69
|
let schema: import('graphql').GraphQLSchema | undefined;
|
|
67
70
|
const { resolvers, aliases, stored } = options.part;
|
|
68
71
|
// introspection (`__typename`, `__type`, `__schema` and the `__Type`/`__Field`/… meta types) is the vendor's schema
|
|
@@ -71,7 +74,7 @@ export function graphqlEndpoint<C>(options: {
|
|
|
71
74
|
const modeled = (type: string, field: string): boolean =>
|
|
72
75
|
field.startsWith('__') || type.startsWith('__') || `${type}.${field}` in resolvers || !!aliases?.[type]?.[field] || !!stored?.[type]?.includes(field) || !!stored?.[type]?.includes(snake(field));
|
|
73
76
|
return async (request) => {
|
|
74
|
-
const g = await
|
|
77
|
+
const g = await (lib ??= loadLibrary());
|
|
75
78
|
schema ??= g.buildSchema(options.sdl, { assumeValidSDL: true });
|
|
76
79
|
const payload = (await request.clone().json().catch(() => ({}))) as { query?: string; variables?: Record<string, unknown>; operationName?: string };
|
|
77
80
|
let document: import('graphql').DocumentNode;
|
package/src/pack-fetch.ts
CHANGED
|
@@ -35,7 +35,7 @@ import { worldNow } from './world-clock.ts';
|
|
|
35
35
|
import type { WebSocketUpgrade, WebSocketPeer } from './serve-http.ts';
|
|
36
36
|
import { MACHINE_POOL, POOL_KINDS, resetFakePool } from './machines.ts';
|
|
37
37
|
import { applyTwinWrite } from './serve.ts';
|
|
38
|
-
import { graphqlEndpoint, type GraphqlPart } from './graphql-wire.ts';
|
|
38
|
+
import { graphqlEndpoint, type GraphqlPart, type GraphqlLibraryLoader } from './graphql-wire.ts';
|
|
39
39
|
import { gzipSync } from 'node:zlib';
|
|
40
40
|
import { decompress } from './bytes.ts';
|
|
41
41
|
import { decodedBodyLimit, oversizedBody, RequestBodyTooLargeError } from './request-body.ts';
|
|
@@ -71,7 +71,7 @@ export type PackParts = {
|
|
|
71
71
|
lanes?: Record<string, LanePart>;
|
|
72
72
|
/** `semantics/graphql.ts` with the vendor's schema (`generated/graphql-sdl.gen.json`): the GraphQL wire over the same
|
|
73
73
|
* state, served at the manifest's `graphql.paths` (graphql-wire.ts). */
|
|
74
|
-
graphql?: GraphqlPart<HandlerContext> & { sdl: string };
|
|
74
|
+
graphql?: GraphqlPart<HandlerContext> & { sdl: string; loadLibrary?: GraphqlLibraryLoader };
|
|
75
75
|
/** `semantics/sockets.ts`: each socket's engine, by the id the manifest's `sockets` gives it (sockets.ts). */
|
|
76
76
|
sockets?: Record<string, SocketEngine<HandlerContext>>;
|
|
77
77
|
/** `semantics/board.ts`: the vendor's frames on the World's board, read from its state (`GET /twin/board`). */
|
|
@@ -229,7 +229,7 @@ export function createPackFetch(parts: PackParts, options: PackFetchOptions = {}
|
|
|
229
229
|
// the GraphQL wire over the same state, at the paths the manifest names (graphql-wire.ts)
|
|
230
230
|
const gql = m.graphql && parts.graphql ? m.graphql : undefined;
|
|
231
231
|
const graphql = gql && parts.graphql ? graphqlEndpoint<HandlerContext>({
|
|
232
|
-
sdl: parts.graphql.sdl, part: parts.graphql,
|
|
232
|
+
sdl: parts.graphql.sdl, part: parts.graphql, loadLibrary: parts.graphql.loadLibrary,
|
|
233
233
|
context: async (request) => contextFor(m, { request: request.clone(), operation: { id: 'graphql', method: 'POST', path: gql.paths[0]!, class: 'action' } as DerivedOperation, params: {} }, scope) as Promise<HandlerContext>,
|
|
234
234
|
unmodeled: ({ type, field }) => Response.json({ errors: [{ ...(gql.unmodeled.type ? { type: gql.unmodeled.type } : {}), message: gql.unmodeled.message.replace('{field}', field).replace('{type}', type) }] }, { status: gql.unmodeled.status ?? 200 }),
|
|
235
235
|
mutationRefused: (request) => ((options.readOnly ?? false) || isReadOnlyRequest(request) ? vendorError(m, m.readOnly) : undefined),
|