@volter/twin-standard 1.0.147 → 1.0.148

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.
@@ -219,7 +219,7 @@ export function packFetchFile(dir, name) {
219
219
  ...(hasGap ? [' gap,'] : []),
220
220
  ...(hasSockets ? [' sockets,'] : []),
221
221
  ...(hasLive ? [' live,'] : []),
222
- ...(hasGraphql ? [' graphql: { ...graphql, operations: graphqlSurface.operations as NonNullable<typeof graphql.operations>, sdl: schema.sdl },'] : []),
222
+ ...(hasGraphql ? [' graphql: { ...graphql, operations: graphqlSurface.operations as NonNullable<typeof graphql.operations>, sdl: schema.sdl, loadLibrary: () => import(\'graphql\') },'] : []),
223
223
  ...(screens.length ? [` screens: { ${screens.map((f) => `${JSON.stringify(id(f))}: ${identifier(`screen_${id(f)}`)}`).join(', ')} },`] : []),
224
224
  ...(lanes.length ? [` lanes: ${laneParts},`] : []),
225
225
  ' }, options);',
@@ -523,7 +523,7 @@ const criteria = [
523
523
  },
524
524
  {
525
525
  id: 'kernel-contract', section: 'form',
526
- asks: "every file of src/ imports the kernel through its root, the pack contract, and nothing past it: no `@volter/world-core/runtime` or other entry (cli.ts alone takes args and lifecycle), no node builtin, no other package but @volter/world-ui",
526
+ asks: "every file of src/ imports the kernel through its root, the pack contract, and nothing past it: no `@volter/world-core/runtime` or other entry (cli.ts alone takes args and lifecycle), no node builtin, no other package but @volter/world-ui and the generated GraphQL library loader",
527
527
  check(unit) {
528
528
  const src = join(unit.dir, 'src');
529
529
  if (!existsSync(src))
@@ -532,7 +532,31 @@ const criteria = [
532
532
  for (const f of filesUnder(src).filter((x) => /\.tsx?$/.test(x) && !TEST_FILE.test(x) && !x.startsWith('generated/'))) {
533
533
  // the file's imports, re-exports and dynamic imports as TypeScript reads them (a string that only reads like one,
534
534
  // an error message's "from '<name>'", is none)
535
- const specifiers = ts.preProcessFile(readFileSync(join(src, f), 'utf8'), true, true).importedFiles.map((i) => i.fileName);
535
+ let text = readFileSync(join(src, f), 'utf8');
536
+ if (f === 'fetch.ts') {
537
+ // The generated fetch supplies the kernel wire with the pack-local parser library.
538
+ // Exempt only that exact factory part; other static or dynamic imports still count.
539
+ const source = ts.createSourceFile(f, text, ts.ScriptTarget.Latest, true);
540
+ const loaders = [];
541
+ const visit = (node) => {
542
+ if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword &&
543
+ node.arguments.length === 1 && ts.isStringLiteral(node.arguments[0]) && node.arguments[0].text === 'graphql') {
544
+ const arrow = node.parent, property = arrow.parent;
545
+ const graphql = property.parent?.parent, factory = graphql?.parent?.parent;
546
+ if (ts.isArrowFunction(arrow) && arrow.parameters.length === 0 && arrow.body === node &&
547
+ ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.text === 'loadLibrary' &&
548
+ graphql && ts.isPropertyAssignment(graphql) && ts.isIdentifier(graphql.name) && graphql.name.text === 'graphql' &&
549
+ factory && ts.isCallExpression(factory) && ts.isIdentifier(factory.expression) && factory.expression.text === 'createPackFetch' &&
550
+ factory.arguments[0] === graphql.parent)
551
+ loaders.push({ start: node.getStart(source), end: node.end });
552
+ }
553
+ ts.forEachChild(node, visit);
554
+ };
555
+ visit(source);
556
+ for (const loader of loaders.sort((a, b) => b.start - a.start))
557
+ text = text.slice(0, loader.start) + 'undefined' + text.slice(loader.end);
558
+ }
559
+ const specifiers = ts.preProcessFile(text, true, true).importedFiles.map((i) => i.fileName);
536
560
  for (const from of specifiers) {
537
561
  if (from.startsWith('.'))
538
562
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/twin-standard",
3
- "version": "1.0.147",
3
+ "version": "1.0.148",
4
4
  "description": "The Protocol 3 standard for Volter twin packs: the criteria a pack is graded by, the grader, the gate a pack repository and the twin catalog run on every change and submission, and the spec derivation the grade checks against. Pin a version: every place a pack is judged judges by that standard.",
5
5
  "keywords": [
6
6
  "twin",
@@ -75,7 +75,7 @@
75
75
  "yaml": "2.9.0"
76
76
  },
77
77
  "peerDependencies": {
78
- "@volter/world-core": "3.0.154",
78
+ "@volter/world-core": "3.0.155",
79
79
  "@volter/world-runtime": "*",
80
80
  "playwright": "^1.63.0"
81
81
  },
@@ -209,7 +209,7 @@ export function packFetchFile(dir: string, name: string): string {
209
209
  ...(hasGap ? [' gap,'] : []),
210
210
  ...(hasSockets ? [' sockets,'] : []),
211
211
  ...(hasLive ? [' live,'] : []),
212
- ...(hasGraphql ? [' graphql: { ...graphql, operations: graphqlSurface.operations as NonNullable<typeof graphql.operations>, sdl: schema.sdl },'] : []),
212
+ ...(hasGraphql ? [' graphql: { ...graphql, operations: graphqlSurface.operations as NonNullable<typeof graphql.operations>, sdl: schema.sdl, loadLibrary: () => import(\'graphql\') },'] : []),
213
213
  ...(screens.length ? [` screens: { ${screens.map((f) => `${JSON.stringify(id(f))}: ${identifier(`screen_${id(f)}`)}`).join(', ')} },`] : []),
214
214
  ...(lanes.length ? [` lanes: ${laneParts},`] : []),
215
215
  ' }, options);',
package/src/protocol-3.ts CHANGED
@@ -452,7 +452,7 @@ const criteria: Criterion[] = [
452
452
  },
453
453
  {
454
454
  id: 'kernel-contract', section: 'form',
455
- asks: "every file of src/ imports the kernel through its root, the pack contract, and nothing past it: no `@volter/world-core/runtime` or other entry (cli.ts alone takes args and lifecycle), no node builtin, no other package but @volter/world-ui",
455
+ asks: "every file of src/ imports the kernel through its root, the pack contract, and nothing past it: no `@volter/world-core/runtime` or other entry (cli.ts alone takes args and lifecycle), no node builtin, no other package but @volter/world-ui and the generated GraphQL library loader",
456
456
  check(unit) {
457
457
  const src = join(unit.dir, 'src');
458
458
  if (!existsSync(src)) return fail('src/ is missing');
@@ -460,7 +460,29 @@ const criteria: Criterion[] = [
460
460
  for (const f of filesUnder(src).filter((x) => /\.tsx?$/.test(x) && !TEST_FILE.test(x) && !x.startsWith('generated/'))) {
461
461
  // the file's imports, re-exports and dynamic imports as TypeScript reads them (a string that only reads like one,
462
462
  // an error message's "from '<name>'", is none)
463
- const specifiers = ts.preProcessFile(readFileSync(join(src, f), 'utf8'), true, true).importedFiles.map((i) => i.fileName);
463
+ let text = readFileSync(join(src, f), 'utf8');
464
+ if (f === 'fetch.ts') {
465
+ // The generated fetch supplies the kernel wire with the pack-local parser library.
466
+ // Exempt only that exact factory part; other static or dynamic imports still count.
467
+ const source = ts.createSourceFile(f, text, ts.ScriptTarget.Latest, true);
468
+ const loaders: Array<{ start: number; end: number }> = [];
469
+ const visit = (node: ts.Node): void => {
470
+ if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword &&
471
+ node.arguments.length === 1 && ts.isStringLiteral(node.arguments[0]!) && node.arguments[0]!.text === 'graphql') {
472
+ const arrow = node.parent, property = arrow.parent;
473
+ const graphql = property.parent?.parent, factory = graphql?.parent?.parent;
474
+ if (ts.isArrowFunction(arrow) && arrow.parameters.length === 0 && arrow.body === node &&
475
+ ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.text === 'loadLibrary' &&
476
+ graphql && ts.isPropertyAssignment(graphql) && ts.isIdentifier(graphql.name) && graphql.name.text === 'graphql' &&
477
+ factory && ts.isCallExpression(factory) && ts.isIdentifier(factory.expression) && factory.expression.text === 'createPackFetch' &&
478
+ factory.arguments[0] === graphql.parent) loaders.push({ start: node.getStart(source), end: node.end });
479
+ }
480
+ ts.forEachChild(node, visit);
481
+ };
482
+ visit(source);
483
+ for (const loader of loaders.sort((a, b) => b.start - a.start)) text = text.slice(0, loader.start) + 'undefined' + text.slice(loader.end);
484
+ }
485
+ const specifiers = ts.preProcessFile(text, true, true).importedFiles.map((i) => i.fileName);
464
486
  for (const from of specifiers) {
465
487
  if (from.startsWith('.')) continue;
466
488
  if (from === '@volter/world-core' || from === '@volter/world-ui') continue;