@datamoc/mw_games 0.6.0 → 0.7.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.
Files changed (54) hide show
  1. package/README.md +51 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/mw_games.global.js +24 -21
  7. package/dist/mwl/actors.d.ts +16 -0
  8. package/dist/mwl/actors.d.ts.map +1 -0
  9. package/dist/mwl/actors.js +25 -0
  10. package/dist/mwl/actors.js.map +1 -0
  11. package/dist/mwl/catalog.d.ts +13 -0
  12. package/dist/mwl/catalog.d.ts.map +1 -0
  13. package/dist/mwl/catalog.js +52 -0
  14. package/dist/mwl/catalog.js.map +1 -0
  15. package/dist/mwl/compiler.d.ts +45 -0
  16. package/dist/mwl/compiler.d.ts.map +1 -0
  17. package/dist/mwl/compiler.js +69 -0
  18. package/dist/mwl/compiler.js.map +1 -0
  19. package/dist/mwl/content.d.ts +54 -0
  20. package/dist/mwl/content.d.ts.map +1 -0
  21. package/dist/mwl/content.js +97 -0
  22. package/dist/mwl/content.js.map +1 -0
  23. package/dist/mwl/expression.d.ts +21 -0
  24. package/dist/mwl/expression.d.ts.map +1 -0
  25. package/dist/mwl/expression.js +100 -0
  26. package/dist/mwl/expression.js.map +1 -0
  27. package/dist/mwl/grammar.d.ts +39 -0
  28. package/dist/mwl/grammar.d.ts.map +1 -0
  29. package/dist/mwl/grammar.js +204 -0
  30. package/dist/mwl/grammar.js.map +1 -0
  31. package/dist/mwl/hooks.d.ts +81 -0
  32. package/dist/mwl/hooks.d.ts.map +1 -0
  33. package/dist/mwl/hooks.js +78 -0
  34. package/dist/mwl/hooks.js.map +1 -0
  35. package/dist/mwl/index.d.ts +21 -0
  36. package/dist/mwl/index.d.ts.map +1 -0
  37. package/dist/mwl/index.js +11 -0
  38. package/dist/mwl/index.js.map +1 -0
  39. package/dist/mwl/persistence.d.ts +15 -0
  40. package/dist/mwl/persistence.d.ts.map +1 -0
  41. package/dist/mwl/persistence.js +33 -0
  42. package/dist/mwl/persistence.js.map +1 -0
  43. package/dist/mwl/runtime.d.ts +169 -0
  44. package/dist/mwl/runtime.d.ts.map +1 -0
  45. package/dist/mwl/runtime.js +519 -0
  46. package/dist/mwl/runtime.js.map +1 -0
  47. package/dist/mwl/schema.d.ts +20 -0
  48. package/dist/mwl/schema.d.ts.map +1 -0
  49. package/dist/mwl/schema.js +351 -0
  50. package/dist/mwl/schema.js.map +1 -0
  51. package/dist/version.d.ts +1 -1
  52. package/dist/version.js +1 -1
  53. package/package.json +7 -1
  54. package/tools/mwl.mjs +153 -0
@@ -0,0 +1,204 @@
1
+ export class MwlSyntaxError extends Error {
2
+ constructor(diagnostic) {
3
+ super(`${diagnostic.location.file}:${diagnostic.location.line}:${diagnostic.location.column}: ${diagnostic.message}`);
4
+ this.name = 'MwlSyntaxError';
5
+ this.diagnostic = diagnostic;
6
+ }
7
+ }
8
+ const directiveNames = new Set(['define', 'enddef', 'arg', 'ifdef', 'ifndef', 'else', 'endif', 'include']);
9
+ export function preprocess(source, options = {}) {
10
+ const macros = new Map();
11
+ const defines = new Set(options.defines ?? []);
12
+ const lines = source.split(/\r?\n/);
13
+ const output = [];
14
+ const active = [true];
15
+ let macro = null;
16
+ for (let index = 0; index < lines.length; index++) {
17
+ const line = lines[index];
18
+ const directive = /^\s*#([A-Za-z_][\w-]*)(?:\s+(.*))?$/.exec(line);
19
+ if (directive && directiveNames.has(directive[1])) {
20
+ const word = directive[1];
21
+ const argument = directive[2]?.trim() ?? '';
22
+ if (word === 'define') {
23
+ if (!active.at(-1) || macro)
24
+ continue;
25
+ const parts = splitWords(argument);
26
+ if (parts.length === 0)
27
+ throw syntax('MWL_DEFINE', 'macro name is required', options.file, index, line);
28
+ macro = { name: parts[0], parameters: parts.slice(1), body: [] };
29
+ defines.add(parts[0]);
30
+ continue;
31
+ }
32
+ if (word === 'arg') {
33
+ if (macro && argument)
34
+ macro.parameters.push(argument.split(/\s+/)[0]);
35
+ continue;
36
+ }
37
+ if (word === 'enddef') {
38
+ if (!macro)
39
+ throw syntax('MWL_ENDDEF', 'unexpected #enddef', options.file, index, line);
40
+ macros.set(macro.name, { name: macro.name, parameters: macro.parameters, body: macro.body.join('\n') });
41
+ macro = null;
42
+ continue;
43
+ }
44
+ if (word === 'ifdef' || word === 'ifndef') {
45
+ const present = defines.has(argument);
46
+ active.push(active.at(-1) === true && (word === 'ifdef' ? present : !present));
47
+ continue;
48
+ }
49
+ if (word === 'else') {
50
+ if (active.length < 2)
51
+ throw syntax('MWL_ELSE', 'unexpected #else', options.file, index, line);
52
+ active[active.length - 1] = active[active.length - 2] && !active.at(-1);
53
+ continue;
54
+ }
55
+ if (word === 'endif') {
56
+ if (active.length < 2)
57
+ throw syntax('MWL_ENDIF', 'unexpected #endif', options.file, index, line);
58
+ active.pop();
59
+ continue;
60
+ }
61
+ if (word === 'include') {
62
+ if (active.at(-1)) {
63
+ const included = options.includes?.[unquote(argument)];
64
+ if (included === undefined)
65
+ throw syntax('MWL_INCLUDE', `include not supplied: ${argument}`, options.file, index, line);
66
+ output.push(preprocess(included, options));
67
+ }
68
+ continue;
69
+ }
70
+ }
71
+ if (macro) {
72
+ if (active.at(-1))
73
+ macro.body.push(line);
74
+ continue;
75
+ }
76
+ if (active.at(-1) && !/^\s*#/.test(line))
77
+ output.push(line);
78
+ }
79
+ if (macro)
80
+ throw syntax('MWL_ENDDEF', `macro ${macro.name} is missing #enddef`, options.file, lines.length - 1, lines.at(-1) ?? '');
81
+ if (active.length !== 1)
82
+ throw syntax('MWL_ENDIF', 'conditional is missing #endif', options.file, lines.length - 1, lines.at(-1) ?? '');
83
+ return expandMacros(output.join('\n'), macros, options);
84
+ }
85
+ function expandMacros(source, macros, options) {
86
+ return source.replace(/\{([^{}]*)\}/g, (whole, inner) => {
87
+ const parts = splitWords(inner);
88
+ const definition = macros.get(parts[0]);
89
+ if (!definition)
90
+ return whole;
91
+ let body = definition.body;
92
+ for (let i = 0; i < definition.parameters.length; i++) {
93
+ const parameter = definition.parameters[i];
94
+ const keyword = parts.find((part) => part.startsWith(`${parameter}=`));
95
+ const value = keyword ? keyword.slice(parameter.length + 1) : (parts[i + 1] ?? '');
96
+ body = body.replaceAll(`{${parameter}}`, value);
97
+ }
98
+ return expandMacros(body, macros, options);
99
+ });
100
+ }
101
+ export function parse(source, file = '<mwl>') {
102
+ const roots = [];
103
+ const stack = [];
104
+ const lines = source.split(/\r?\n/);
105
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
106
+ const raw = lines[lineIndex];
107
+ const line = raw.trim();
108
+ if (!line || line.startsWith('#'))
109
+ continue;
110
+ const location = { file, line: lineIndex + 1, column: Math.max(1, raw.indexOf(line) + 1) };
111
+ const opening = /^\[([A-Za-z_][\w-]*)\]$/.exec(line);
112
+ if (opening) {
113
+ const node = { tag: opening[1], attributes: {}, children: [], location, gettext: [] };
114
+ if (stack.length)
115
+ stack.at(-1).children.push(node);
116
+ else
117
+ roots.push(node);
118
+ stack.push(node);
119
+ continue;
120
+ }
121
+ const closing = /^\[\/([A-Za-z_][\w-]*)\]$/.exec(line);
122
+ if (closing) {
123
+ const node = stack.pop();
124
+ if (!node || node.tag !== closing[1])
125
+ throw new MwlSyntaxError({
126
+ code: 'MWL_TAG',
127
+ message: `mismatched closing tag ${closing[1]}`,
128
+ location,
129
+ lineText: raw,
130
+ });
131
+ continue;
132
+ }
133
+ const attribute = /^([A-Za-z_][\w-]*)\s*=\s*(.*)$/.exec(line);
134
+ if (attribute && stack.length) {
135
+ const node = stack.at(-1);
136
+ if (isGettext(attribute[2]))
137
+ node.gettext.push(attribute[1]);
138
+ node.attributes[attribute[1]] = parseValue(attribute[2], location, raw);
139
+ continue;
140
+ }
141
+ throw new MwlSyntaxError({
142
+ code: 'MWL_TOKEN',
143
+ message: 'expected a tag or key=value attribute',
144
+ location,
145
+ lineText: raw,
146
+ });
147
+ }
148
+ if (stack.length) {
149
+ const node = stack.at(-1);
150
+ throw new MwlSyntaxError({ code: 'MWL_TAG', message: `unclosed tag ${node.tag}`, location: node.location });
151
+ }
152
+ return roots;
153
+ }
154
+ export function parseValue(raw, location, lineText = raw) {
155
+ // The gettext marker is `_` followed by a quoted string. Requiring the
156
+ // quote is deliberate: values such as `aliasof=_bas` start with an
157
+ // underscore and must survive unchanged.
158
+ let value = raw.trim();
159
+ const marker = /^_\s*"/.exec(value);
160
+ if (marker)
161
+ value = value.slice(marker[0].length - 1);
162
+ if (value.startsWith('"')) {
163
+ if (!value.endsWith('"') || value.length < 2)
164
+ throw new MwlSyntaxError({ code: 'MWL_STRING', message: 'unterminated quoted value', location, lineText });
165
+ return value.slice(1, -1).replaceAll('""', '"');
166
+ }
167
+ return value;
168
+ }
169
+ /** True when a raw attribute value carries the gettext marker `_ "..."`. */
170
+ export function isGettext(raw) {
171
+ return /^_\s*"/.test(raw.trim());
172
+ }
173
+ function splitWords(value) {
174
+ const result = [];
175
+ let current = '';
176
+ let quoted = false;
177
+ for (let i = 0; i < value.length; i++) {
178
+ const character = value[i];
179
+ if (character === '"')
180
+ quoted = !quoted;
181
+ if (/\s/.test(character) && !quoted) {
182
+ if (current)
183
+ result.push(current);
184
+ current = '';
185
+ }
186
+ else
187
+ current += character;
188
+ }
189
+ if (current)
190
+ result.push(current);
191
+ return result;
192
+ }
193
+ function unquote(value) {
194
+ return value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value;
195
+ }
196
+ function syntax(code, message, file, index, lineText) {
197
+ return new MwlSyntaxError({
198
+ code,
199
+ message,
200
+ location: { file: file ?? '<mwl>', line: index + 1, column: 1 },
201
+ lineText,
202
+ });
203
+ }
204
+ //# sourceMappingURL=grammar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.js","sourceRoot":"","sources":["../../src/mwl/grammar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { MwlCompiledGame } from './compiler.ts';
2
+ import type { MwlDiagnostic, MwlLocation } from './grammar.ts';
3
+ /**
4
+ * The hook boundary described in `4MWG/ARCHITECTURE.md`. Hooks are the only
5
+ * place JavaScript appears in MWL content. They are referenced by
6
+ * `type:name`, resolved by the tooling, and bundled ahead of time; the runtime
7
+ * never evaluates JavaScript from content.
8
+ */
9
+ export type HookType = 'predicate' | 'modifier' | 'generator' | 'command' | 'ai' | 'migration';
10
+ export declare const hookTypes: readonly HookType[];
11
+ /** What a hook may read: a snapshot of the world, never engine internals. */
12
+ export interface HookWorld {
13
+ readonly variables: Readonly<Record<string, string | number | boolean>>;
14
+ readonly units: Readonly<Record<string, {
15
+ readonly hp: number;
16
+ readonly x: number;
17
+ readonly y: number;
18
+ readonly alive: boolean;
19
+ readonly type?: string;
20
+ readonly side?: number;
21
+ }>>;
22
+ readonly sides: Readonly<Record<string, {
23
+ readonly gold: number;
24
+ readonly income: number;
25
+ }>>;
26
+ readonly turn: number;
27
+ }
28
+ /** What a hook may ask the engine to do. This is the whole command surface. */
29
+ export interface Emit {
30
+ move(unit: string, x: number, y: number): void;
31
+ attack(attacker: string, defender: string, weapon?: string): void;
32
+ spawn(type: string, side: number, x: number, y: number): void;
33
+ kill(unit: string): void;
34
+ gold(side: number, delta: number): void;
35
+ setVariable(name: string, value: string | number | boolean): void;
36
+ message(speaker: string, text: string): void;
37
+ endTurn(): void;
38
+ win(side: number): void;
39
+ lose(side: number): void;
40
+ }
41
+ export type HookContext = Readonly<Record<string, string>>;
42
+ export type PredicateHook = (world: HookWorld, context: HookContext) => boolean;
43
+ export type ModifierHook = (value: number, world: HookWorld, context: HookContext) => number;
44
+ export type GeneratorHook = (world: HookWorld, context: HookContext) => unknown;
45
+ export type CommandHook = (world: HookWorld, emit: Emit, context: HookContext) => void;
46
+ export type AiHook = (world: HookWorld, emit: Emit, context: HookContext) => void;
47
+ export type MigrationHook = (saved: unknown, context: HookContext) => unknown;
48
+ export interface HookTypeMap {
49
+ predicate: PredicateHook;
50
+ modifier: ModifierHook;
51
+ generator: GeneratorHook;
52
+ command: CommandHook;
53
+ ai: AiHook;
54
+ migration: MigrationHook;
55
+ }
56
+ export interface HookReference {
57
+ readonly type: HookType;
58
+ readonly name: string;
59
+ readonly location?: MwlLocation;
60
+ }
61
+ /** Parse a `type:name` hook reference, or null when it does not match. */
62
+ export declare function parseHookReference(value: string): {
63
+ type: HookType;
64
+ name: string;
65
+ } | null;
66
+ /**
67
+ * Every hook a compiled game references, deduplicated by `type:name` and
68
+ * ordered so the output is stable.
69
+ */
70
+ export declare function collectHookReferences(game: MwlCompiledGame): HookReference[];
71
+ /**
72
+ * Report a reference that has no implementation, using the same diagnostic
73
+ * shape as the schema validator. `available` holds `type:name` keys.
74
+ */
75
+ export declare function validateHookReferences(references: readonly HookReference[], available: Iterable<string>): MwlDiagnostic[];
76
+ /**
77
+ * Emit the declaration a hooks module must satisfy, so a project typechecks its
78
+ * hooks against the exact references its content uses.
79
+ */
80
+ export declare function emitHooksDeclaration(references: readonly HookReference[]): string;
81
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/mwl/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ export const hookTypes = ['predicate', 'modifier', 'generator', 'command', 'ai', 'migration'];
2
+ /** Parse a `type:name` hook reference, or null when it does not match. */
3
+ export function parseHookReference(value) {
4
+ const separator = value.indexOf(':');
5
+ if (separator <= 0)
6
+ return null;
7
+ const type = value.slice(0, separator);
8
+ const name = value.slice(separator + 1).trim();
9
+ if (!hookTypes.includes(type) || !name)
10
+ return null;
11
+ return { type, name };
12
+ }
13
+ /** Attributes whose value is a hook reference. */
14
+ const hookAttributes = new Set(['hook', 'migration']);
15
+ /**
16
+ * Every hook a compiled game references, deduplicated by `type:name` and
17
+ * ordered so the output is stable.
18
+ */
19
+ export function collectHookReferences(game) {
20
+ const found = new Map();
21
+ const visit = (node) => {
22
+ for (const [key, value] of Object.entries(node.attributes)) {
23
+ if (hookAttributes.has(key))
24
+ add(value, node.location);
25
+ // A `[hook]` call carries its reference in `name`.
26
+ if (node.tag === 'hook' && key === 'name')
27
+ add(value, node.location);
28
+ }
29
+ node.children.forEach(visit);
30
+ };
31
+ const add = (value, location) => {
32
+ const reference = parseHookReference(value);
33
+ if (!reference)
34
+ return;
35
+ const id = `${reference.type}:${reference.name}`;
36
+ if (!found.has(id))
37
+ found.set(id, { ...reference, location });
38
+ };
39
+ game.roots.forEach(visit);
40
+ return [...found.values()].sort((a, b) => a.type.localeCompare(b.type) || a.name.localeCompare(b.name));
41
+ }
42
+ /**
43
+ * Report a reference that has no implementation, using the same diagnostic
44
+ * shape as the schema validator. `available` holds `type:name` keys.
45
+ */
46
+ export function validateHookReferences(references, available) {
47
+ const implemented = new Set(available);
48
+ const diagnostics = [];
49
+ for (const reference of references) {
50
+ const id = `${reference.type}:${reference.name}`;
51
+ if (!implemented.has(id))
52
+ diagnostics.push({
53
+ code: 'MWL_HOOK',
54
+ message: `hook ${id} is not implemented`,
55
+ location: reference.location ?? { file: '<hook>', line: 0, column: 0 },
56
+ });
57
+ }
58
+ return diagnostics;
59
+ }
60
+ /**
61
+ * Emit the declaration a hooks module must satisfy, so a project typechecks its
62
+ * hooks against the exact references its content uses.
63
+ */
64
+ export function emitHooksDeclaration(references) {
65
+ const lines = [];
66
+ lines.push('// Generated by mwl - do not edit.');
67
+ lines.push("import type { AiHook, CommandHook, GeneratorHook, MigrationHook, ModifierHook, PredicateHook } from '@datamoc/mw_games/mwl';");
68
+ lines.push('');
69
+ lines.push('export interface MwlHooks {');
70
+ for (const reference of references) {
71
+ const hookType = `${reference.type[0].toUpperCase()}${reference.type.slice(1)}Hook`;
72
+ lines.push(`\t'${reference.type}:${reference.name}': ${hookType};`);
73
+ }
74
+ lines.push('}');
75
+ lines.push('');
76
+ return lines.join('\n');
77
+ }
78
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/mwl/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export { MwlSyntaxError, isGettext, parse, parseValue, preprocess } from './grammar.ts';
2
+ export type { MwlDiagnostic, MwlLocation, MwlNode, MwlPreprocessOptions } from './grammar.ts';
3
+ export { schema01, validate } from './schema.ts';
4
+ export type { MwlTagSchema, MwlValueType } from './schema.ts';
5
+ export { compile, compileNodes, emitModule, extractCatalog } from './compiler.ts';
6
+ export type { MwlCatalog, MwlCatalogOptions, MwlCompileOptions, MwlCompiledGame, MwlCompiledNode } from './compiler.ts';
7
+ export { collectHookReferences, emitHooksDeclaration, hookTypes, parseHookReference, validateHookReferences, } from './hooks.ts';
8
+ export type { AiHook, CommandHook, Emit, GeneratorHook, HookContext, HookReference, HookType, HookTypeMap, HookWorld, MigrationHook, ModifierHook, PredicateHook, } from './hooks.ts';
9
+ export { createWorld, execute, MwlRuntime, parseTerrain } from './runtime.ts';
10
+ export type { MwlCommand, MwlHookRegistry, MwlMap, MwlMapStart, MwlRuntimeOptions, MwlWorld } from './runtime.ts';
11
+ export { contentCatalog } from './content.ts';
12
+ export type { MwlContentCatalog, MwlEffectDefinition, MwlItemDefinition, MwlLootDefinition, MwlMonsterDefinition, MwlStatusDefinition, MwlTurnClockDefinition, } from './content.ts';
13
+ export { evaluateExpression, parseExpression } from './expression.ts';
14
+ export type { MwlExpression, MwlExpressionContext } from './expression.ts';
15
+ export { effectToModifier, inventoryItem, itemDefinition } from './actors.ts';
16
+ export type { MwlActorItem, MwlEquipment } from './actors.ts';
17
+ export { validateCatalog, validateCatalogNodes } from './catalog.ts';
18
+ export type { MwlValidationOptions } from './catalog.ts';
19
+ export { decodeSave, encodeSave, validateWorld } from './persistence.ts';
20
+ export type { MwlMigration, MwlPersistenceOptions, MwlSaveEnvelope } from './persistence.ts';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mwl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACxF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC9F,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClF,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,SAAS,EACT,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,MAAM,EACN,WAAW,EACX,IAAI,EACJ,aAAa,EACb,WAAW,EACX,aAAa,EACb,QAAQ,EACR,WAAW,EACX,SAAS,EACT,aAAa,EACb,YAAY,EACZ,aAAa,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC9E,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACrE,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export { MwlSyntaxError, isGettext, parse, parseValue, preprocess } from './grammar.js';
2
+ export { schema01, validate } from './schema.js';
3
+ export { compile, compileNodes, emitModule, extractCatalog } from './compiler.js';
4
+ export { collectHookReferences, emitHooksDeclaration, hookTypes, parseHookReference, validateHookReferences, } from './hooks.js';
5
+ export { createWorld, execute, MwlRuntime, parseTerrain } from './runtime.js';
6
+ export { contentCatalog } from './content.js';
7
+ export { evaluateExpression, parseExpression } from './expression.js';
8
+ export { effectToModifier, inventoryItem, itemDefinition } from './actors.js';
9
+ export { validateCatalog, validateCatalogNodes } from './catalog.js';
10
+ export { decodeSave, encodeSave, validateWorld } from './persistence.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mwl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAExF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,SAAS,EACT,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,YAAY,CAAC;AAepB,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAU9C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { MwlWorld } from './runtime.ts';
2
+ export interface MwlSaveEnvelope {
3
+ readonly format: 'mwl-save';
4
+ readonly version: number;
5
+ readonly world: MwlWorld;
6
+ }
7
+ export type MwlMigration = (world: MwlWorld) => MwlWorld;
8
+ export interface MwlPersistenceOptions {
9
+ readonly version: number;
10
+ readonly migrations?: Readonly<Record<number, MwlMigration>>;
11
+ }
12
+ export declare function encodeSave(world: MwlWorld, options: MwlPersistenceOptions): string;
13
+ export declare function decodeSave(snapshot: string, options: MwlPersistenceOptions): MwlWorld;
14
+ export declare function validateWorld(value: unknown): MwlWorld;
15
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/mwl/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CACzB;AACD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,CAAC;AACzD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;CAC7D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAGlF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,QAAQ,CAWrF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAOtD"}
@@ -0,0 +1,33 @@
1
+ export function encodeSave(world, options) {
2
+ if (!Number.isInteger(options.version) || options.version < 1)
3
+ throw new Error('MWL save version must be a positive integer');
4
+ return JSON.stringify({ format: 'mwl-save', version: options.version, world });
5
+ }
6
+ export function decodeSave(snapshot, options) {
7
+ const value = JSON.parse(snapshot);
8
+ const envelope = isEnvelope(value) ? value : { format: 'mwl-save', version: 1, world: value };
9
+ if (envelope.version > options.version)
10
+ throw new Error(`MWL save version ${envelope.version} is newer than supported version ${options.version}`);
11
+ let world = validateWorld(envelope.world);
12
+ for (let version = envelope.version; version < options.version; version++) {
13
+ const migration = options.migrations?.[version + 1];
14
+ if (!migration)
15
+ throw new Error(`missing MWL save migration to version ${version + 1}`);
16
+ world = validateWorld(migration(world));
17
+ }
18
+ return world;
19
+ }
20
+ export function validateWorld(value) {
21
+ if (!value || typeof value !== 'object')
22
+ throw new Error('invalid MWL saved world');
23
+ const world = value;
24
+ if (!Number.isInteger(world.turn) || !world.variables || typeof world.variables !== 'object' || !world.units || typeof world.units !== 'object')
25
+ throw new Error('invalid MWL saved world: turn, variables, and units are required');
26
+ if (world.status !== undefined && !['playing', 'won', 'lost'].includes(world.status))
27
+ throw new Error('invalid MWL saved world status');
28
+ return structuredClone(world);
29
+ }
30
+ function isEnvelope(value) {
31
+ return !!value && typeof value === 'object' && value.format === 'mwl-save' && typeof value.version === 'number' && 'world' in value;
32
+ }
33
+ //# sourceMappingURL=persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/mwl/persistence.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,UAAU,CAAC,KAAe,EAAE,OAA8B;IACzE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC9H,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAA4B,CAAC,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,OAA8B;IAC1E,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAmB,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,KAAiB,EAAE,CAAC;IACnH,IAAI,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,OAAO,oCAAoC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACnJ,IAAI,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,KAAK,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3E,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC;QACxF,KAAK,GAAG,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC3C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACpF,MAAM,KAAK,GAAG,KAA0B,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC9I,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACrF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACxI,OAAO,eAAe,CAAC,KAAiB,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IACjC,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAK,KAA8B,CAAC,MAAM,KAAK,UAAU,IAAI,OAAQ,KAA+B,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC;AAC1L,CAAC"}