@patterkit/compiler 0.2.8 → 0.3.0

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/index.cjs CHANGED
@@ -37,7 +37,7 @@ function compileExpression(src, foreign) {
37
37
  }
38
38
  function validateConditions(input, options = {}) {
39
39
  const issues = [];
40
- const foreign = options.foreignScopes;
40
+ const foreign = (0, import_dialect.withEngineScopes)(options.foreignScopes);
41
41
  const dialect = (0, import_dialect.dialectWithForeignScopes)(foreign);
42
42
  const readOnly = readOnlyForeignTargets(foreign);
43
43
  const opaqueForeign = opaqueForeignTokens(foreign);
@@ -132,10 +132,11 @@ function validateInterpolation(input, options = {}) {
132
132
  const voiced = input.project.voiced ?? false;
133
133
  const tables = (input.locales ?? []).map((l) => ({ locale: l.locale, strings: l.strings }));
134
134
  const defaultLocale = input.project.locales.default;
135
- const opaqueForeign = opaqueForeignTokens(options.foreignScopes);
136
- const isScopeToken = scopeTokenTest(options.foreignScopes);
135
+ const foreign = (0, import_dialect.withEngineScopes)(options.foreignScopes);
136
+ const opaqueForeign = opaqueForeignTokens(foreign);
137
+ const isScopeToken = scopeTokenTest(foreign);
137
138
  for (const scene of input.scenes) {
138
- const schema = (0, import_dialect.buildSchema)(input.project, scene.sceneProps, options.foreignScopes);
139
+ const schema = (0, import_dialect.buildSchema)(input.project, scene.sceneProps, foreign);
139
140
  const known = (ref) => {
140
141
  const { scope, name } = (0, import_dialect.splitRef)(ref, isScopeToken);
141
142
  if (opaqueForeign.has(scope)) return true;
@@ -303,11 +304,33 @@ function compileScene(scene, foreign) {
303
304
  blocks: scene.blocks.map((b) => compileBlock(b, foreign))
304
305
  };
305
306
  }
307
+ function externalScopesIn(scenes) {
308
+ const found = /* @__PURE__ */ new Set();
309
+ const external = new Set(import_dialect2.EXTERNAL_SCOPES);
310
+ const walk = (node) => {
311
+ if (!Array.isArray(node) && (node === null || typeof node !== "object")) return;
312
+ if (Array.isArray(node)) {
313
+ if (node[0] === "sv" && typeof node[1] === "string" && external.has(node[1])) found.add(node[1]);
314
+ for (const n of node) walk(n);
315
+ return;
316
+ }
317
+ const o = node;
318
+ if (o["kind"] === "set" && typeof o["target"] === "string") {
319
+ const head = o["target"].replace(/^@/, "").split(".")[0];
320
+ if (o["target"].includes(".") && external.has(head)) found.add(head);
321
+ }
322
+ for (const v of Object.values(o)) walk(v);
323
+ };
324
+ walk(scenes);
325
+ return [...found].sort();
326
+ }
306
327
  function exportBundle(input) {
307
328
  const { project, scenes, locales = [], includeLocales } = input;
308
329
  const foreignScopes = input.foreignScopes ?? (0, import_dialect2.hostScopesToSpec)(project.scopeRegistry);
330
+ const compileScopes = (0, import_dialect2.withEngineScopes)(foreignScopes);
309
331
  const scenesOut = {};
310
- for (const scene of scenes) scenesOut[scene.id] = compileScene(scene, foreignScopes);
332
+ for (const scene of scenes) scenesOut[scene.id] = compileScene(scene, compileScopes);
333
+ const externalScopes = externalScopesIn(scenesOut);
311
334
  const strings = {};
312
335
  for (const loc of locales) {
313
336
  if (includeLocales && !includeLocales.includes(loc.locale)) continue;
@@ -363,7 +386,9 @@ function exportBundle(input) {
363
386
  // runtime falls back to `[` / `]` when absent, so default projects keep their exact prior bundle.
364
387
  ...project.closedCaptions ? { closedCaptions: project.closedCaptions } : {},
365
388
  scenes: scenesOut,
366
- strings
389
+ strings,
390
+ // Other engines' scopes the content names, so the engine can say when the game has not registered one.
391
+ ...externalScopes.length > 0 ? { externalScopes } : {}
367
392
  };
368
393
  }
369
394
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  // src/expressions.ts
2
2
  import { compile, parse, validateExpr } from "@wildwinter/expr";
3
- import { dialectWithForeignScopes, buildSchema, extractSlots, splitRef } from "@patterkit/dialect";
3
+ import { dialectWithForeignScopes, buildSchema, extractSlots, splitRef, withEngineScopes } from "@patterkit/dialect";
4
4
  import { walkNodes } from "@patterkit/model";
5
5
  function compileExpression(src, foreign) {
6
6
  return compile(src, dialectWithForeignScopes(foreign));
7
7
  }
8
8
  function validateConditions(input, options = {}) {
9
9
  const issues = [];
10
- const foreign = options.foreignScopes;
10
+ const foreign = withEngineScopes(options.foreignScopes);
11
11
  const dialect = dialectWithForeignScopes(foreign);
12
12
  const readOnly = readOnlyForeignTargets(foreign);
13
13
  const opaqueForeign = opaqueForeignTokens(foreign);
@@ -102,10 +102,11 @@ function validateInterpolation(input, options = {}) {
102
102
  const voiced = input.project.voiced ?? false;
103
103
  const tables = (input.locales ?? []).map((l) => ({ locale: l.locale, strings: l.strings }));
104
104
  const defaultLocale = input.project.locales.default;
105
- const opaqueForeign = opaqueForeignTokens(options.foreignScopes);
106
- const isScopeToken = scopeTokenTest(options.foreignScopes);
105
+ const foreign = withEngineScopes(options.foreignScopes);
106
+ const opaqueForeign = opaqueForeignTokens(foreign);
107
+ const isScopeToken = scopeTokenTest(foreign);
107
108
  for (const scene of input.scenes) {
108
- const schema = buildSchema(input.project, scene.sceneProps, options.foreignScopes);
109
+ const schema = buildSchema(input.project, scene.sceneProps, foreign);
109
110
  const known = (ref) => {
110
111
  const { scope, name } = splitRef(ref, isScopeToken);
111
112
  if (opaqueForeign.has(scope)) return true;
@@ -205,7 +206,7 @@ import { hostScopesToSpec as hostScopesToSpec2 } from "@patterkit/dialect";
205
206
 
206
207
  // src/export.ts
207
208
  import { canonicalStringify, hash32 } from "@patterkit/core";
208
- import { hostScopesToSpec } from "@patterkit/dialect";
209
+ import { hostScopesToSpec, withEngineScopes as withEngineScopes2, EXTERNAL_SCOPES } from "@patterkit/dialect";
209
210
  function compileEffect(e, foreign) {
210
211
  return { kind: "set", target: e.target, value: compileExpression(e.value, foreign) };
211
212
  }
@@ -273,11 +274,33 @@ function compileScene(scene, foreign) {
273
274
  blocks: scene.blocks.map((b) => compileBlock(b, foreign))
274
275
  };
275
276
  }
277
+ function externalScopesIn(scenes) {
278
+ const found = /* @__PURE__ */ new Set();
279
+ const external = new Set(EXTERNAL_SCOPES);
280
+ const walk = (node) => {
281
+ if (!Array.isArray(node) && (node === null || typeof node !== "object")) return;
282
+ if (Array.isArray(node)) {
283
+ if (node[0] === "sv" && typeof node[1] === "string" && external.has(node[1])) found.add(node[1]);
284
+ for (const n of node) walk(n);
285
+ return;
286
+ }
287
+ const o = node;
288
+ if (o["kind"] === "set" && typeof o["target"] === "string") {
289
+ const head = o["target"].replace(/^@/, "").split(".")[0];
290
+ if (o["target"].includes(".") && external.has(head)) found.add(head);
291
+ }
292
+ for (const v of Object.values(o)) walk(v);
293
+ };
294
+ walk(scenes);
295
+ return [...found].sort();
296
+ }
276
297
  function exportBundle(input) {
277
298
  const { project, scenes, locales = [], includeLocales } = input;
278
299
  const foreignScopes = input.foreignScopes ?? hostScopesToSpec(project.scopeRegistry);
300
+ const compileScopes = withEngineScopes2(foreignScopes);
279
301
  const scenesOut = {};
280
- for (const scene of scenes) scenesOut[scene.id] = compileScene(scene, foreignScopes);
302
+ for (const scene of scenes) scenesOut[scene.id] = compileScene(scene, compileScopes);
303
+ const externalScopes = externalScopesIn(scenesOut);
281
304
  const strings = {};
282
305
  for (const loc of locales) {
283
306
  if (includeLocales && !includeLocales.includes(loc.locale)) continue;
@@ -333,7 +356,9 @@ function exportBundle(input) {
333
356
  // runtime falls back to `[` / `]` when absent, so default projects keep their exact prior bundle.
334
357
  ...project.closedCaptions ? { closedCaptions: project.closedCaptions } : {},
335
358
  scenes: scenesOut,
336
- strings
359
+ strings,
360
+ // Other engines' scopes the content names, so the engine can say when the game has not registered one.
361
+ ...externalScopes.length > 0 ? { externalScopes } : {}
337
362
  };
338
363
  }
339
364
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/compiler",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "description": "Patter compiler: compile condition/effect expressions, validate them, and export source to the runtime bundle.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,10 +34,10 @@
34
34
  "build": "tsup src/index.ts --format esm,cjs --dts --clean"
35
35
  },
36
36
  "dependencies": {
37
- "@patterkit/model": "0.5.0",
38
- "@patterkit/core": "0.2.4",
39
- "@patterkit/dialect": "0.1.9",
37
+ "@patterkit/model": "0.6.0",
38
+ "@patterkit/core": "0.2.5",
39
+ "@patterkit/dialect": "0.2.0",
40
40
  "@wildwinter/expr": "^0.5.0",
41
- "@wildwinter/scoperegistry": "^0.6.0"
41
+ "@wildwinter/scoperegistry": "^0.7.0"
42
42
  }
43
43
  }