@bscotch/gcdata 0.14.2

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 (107) hide show
  1. package/LICENSE.md +29 -0
  2. package/README.md +36 -0
  3. package/dist/GameChanger.d.ts +209 -0
  4. package/dist/GameChanger.d.ts.map +1 -0
  5. package/dist/GameChanger.events.d.ts +13 -0
  6. package/dist/GameChanger.events.d.ts.map +1 -0
  7. package/dist/GameChanger.events.js +3 -0
  8. package/dist/GameChanger.events.js.map +1 -0
  9. package/dist/GameChanger.js +478 -0
  10. package/dist/GameChanger.js.map +1 -0
  11. package/dist/SpellChecker.d.ts +31 -0
  12. package/dist/SpellChecker.d.ts.map +1 -0
  13. package/dist/SpellChecker.js +92 -0
  14. package/dist/SpellChecker.js.map +1 -0
  15. package/dist/assert.d.ts +6 -0
  16. package/dist/assert.d.ts.map +1 -0
  17. package/dist/assert.js +22 -0
  18. package/dist/assert.js.map +1 -0
  19. package/dist/cl2.loc.d.ts +1 -0
  20. package/dist/cl2.loc.d.ts.map +1 -0
  21. package/dist/cl2.loc.js +2 -0
  22. package/dist/cl2.loc.js.map +1 -0
  23. package/dist/cl2.quest.d.ts +4 -0
  24. package/dist/cl2.quest.d.ts.map +1 -0
  25. package/dist/cl2.quest.js +4 -0
  26. package/dist/cl2.quest.js.map +1 -0
  27. package/dist/cl2.quest.parse.d.ts +7 -0
  28. package/dist/cl2.quest.parse.d.ts.map +1 -0
  29. package/dist/cl2.quest.parse.js +825 -0
  30. package/dist/cl2.quest.parse.js.map +1 -0
  31. package/dist/cl2.quest.pointers.d.ts +3 -0
  32. package/dist/cl2.quest.pointers.d.ts.map +1 -0
  33. package/dist/cl2.quest.pointers.js +2 -0
  34. package/dist/cl2.quest.pointers.js.map +1 -0
  35. package/dist/cl2.quest.stringify.d.ts +5 -0
  36. package/dist/cl2.quest.stringify.d.ts.map +1 -0
  37. package/dist/cl2.quest.stringify.js +148 -0
  38. package/dist/cl2.quest.stringify.js.map +1 -0
  39. package/dist/cl2.quest.types.d.ts +168 -0
  40. package/dist/cl2.quest.types.d.ts.map +1 -0
  41. package/dist/cl2.quest.types.js +116 -0
  42. package/dist/cl2.quest.types.js.map +1 -0
  43. package/dist/cl2.quest.utils.d.ts +16 -0
  44. package/dist/cl2.quest.utils.d.ts.map +1 -0
  45. package/dist/cl2.quest.utils.js +105 -0
  46. package/dist/cl2.quest.utils.js.map +1 -0
  47. package/dist/cl2.storyline.d.ts +4 -0
  48. package/dist/cl2.storyline.d.ts.map +1 -0
  49. package/dist/cl2.storyline.js +4 -0
  50. package/dist/cl2.storyline.js.map +1 -0
  51. package/dist/cl2.storyline.parse.d.ts +7 -0
  52. package/dist/cl2.storyline.parse.d.ts.map +1 -0
  53. package/dist/cl2.storyline.parse.js +208 -0
  54. package/dist/cl2.storyline.parse.js.map +1 -0
  55. package/dist/cl2.storyline.pointers.d.ts +3 -0
  56. package/dist/cl2.storyline.pointers.d.ts.map +1 -0
  57. package/dist/cl2.storyline.pointers.js +2 -0
  58. package/dist/cl2.storyline.pointers.js.map +1 -0
  59. package/dist/cl2.storyline.stringify.d.ts +4 -0
  60. package/dist/cl2.storyline.stringify.d.ts.map +1 -0
  61. package/dist/cl2.storyline.stringify.js +18 -0
  62. package/dist/cl2.storyline.stringify.js.map +1 -0
  63. package/dist/cl2.storyline.types.d.ts +24 -0
  64. package/dist/cl2.storyline.types.d.ts.map +1 -0
  65. package/dist/cl2.storyline.types.js +87 -0
  66. package/dist/cl2.storyline.types.js.map +1 -0
  67. package/dist/cl2.storyline.utils.d.ts +1 -0
  68. package/dist/cl2.storyline.utils.d.ts.map +1 -0
  69. package/dist/cl2.storyline.utils.js +2 -0
  70. package/dist/cl2.storyline.utils.js.map +1 -0
  71. package/dist/cl2.types.auto.d.ts +22682 -0
  72. package/dist/cl2.types.auto.d.ts.map +1 -0
  73. package/dist/cl2.types.auto.js +2 -0
  74. package/dist/cl2.types.auto.js.map +1 -0
  75. package/dist/cl2.types.editor.d.ts +31 -0
  76. package/dist/cl2.types.editor.d.ts.map +1 -0
  77. package/dist/cl2.types.editor.js +2 -0
  78. package/dist/cl2.types.editor.js.map +1 -0
  79. package/dist/dict.d.ts +3 -0
  80. package/dist/dict.d.ts.map +1 -0
  81. package/dist/dict.js +49777 -0
  82. package/dist/dict.js.map +1 -0
  83. package/dist/helpers.d.ts +44 -0
  84. package/dist/helpers.d.ts.map +1 -0
  85. package/dist/helpers.js +149 -0
  86. package/dist/helpers.js.map +1 -0
  87. package/dist/index.d.ts +9 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +9 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/types.cl2.rumpus.d.ts +190 -0
  92. package/dist/types.cl2.rumpus.d.ts.map +1 -0
  93. package/dist/types.cl2.rumpus.js +30 -0
  94. package/dist/types.cl2.rumpus.js.map +1 -0
  95. package/dist/types.d.ts +586 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.editor.d.ts +25 -0
  98. package/dist/types.editor.d.ts.map +1 -0
  99. package/dist/types.editor.js +2 -0
  100. package/dist/types.editor.js.map +1 -0
  101. package/dist/types.js +98 -0
  102. package/dist/types.js.map +1 -0
  103. package/dist/util.d.ts +42 -0
  104. package/dist/util.d.ts.map +1 -0
  105. package/dist/util.js +272 -0
  106. package/dist/util.js.map +1 -0
  107. package/package.json +32 -0
@@ -0,0 +1,478 @@
1
+ import { pathy } from '@bscotch/pathy';
2
+ import { gameChangerEvents } from './GameChanger.events.js';
3
+ import { SpellChecker } from './SpellChecker.js';
4
+ import { GcdataError, assert } from './assert.js';
5
+ import { gameChangerRumpusMetadataSchema, } from './types.cl2.rumpus.js';
6
+ import { changeSchema, changesSchema, isBschemaBoolean, isBschemaConst, isBschemaEnum, isBschemaNumeric, isBschemaObject, isBschemaString, } from './types.js';
7
+ import { computeTerminalPointers, resolvePointer, resolvePointerInSchema, setValueAtPointer, } from './util.js';
8
+ export class Gcdata {
9
+ data;
10
+ constructor(data) {
11
+ this.data = data;
12
+ }
13
+ get motes() {
14
+ return {
15
+ ...this.data.motes,
16
+ };
17
+ }
18
+ get schemas() {
19
+ return {
20
+ ...this.data.schemas,
21
+ };
22
+ }
23
+ visitMoteData(moteId, visitor, store) {
24
+ const mote = this.getMote(moteId);
25
+ assert(mote, `Cannot visit non-existent mote ${moteId}`);
26
+ const schema = this.getSchema(mote.schema_id);
27
+ assert(schema, `Cannot visit mote ${moteId}: schema not found`);
28
+ const initialCtx = {
29
+ mote,
30
+ schema,
31
+ current: {
32
+ data: mote.data,
33
+ key: undefined,
34
+ pointer: [],
35
+ subschema: schema,
36
+ },
37
+ parent: undefined,
38
+ store,
39
+ };
40
+ const visit = (ctx) => {
41
+ // Call on this node!
42
+ visitor(ctx);
43
+ // Then visit the children
44
+ // Get each data field (there are no arrays, so that simplifies things!)
45
+ const data = ctx.current.data;
46
+ if (typeof data === 'object' && data !== null) {
47
+ for (const key of Object.keys(data)) {
48
+ const pointer = [...ctx.current.pointer, key];
49
+ const subschema = resolvePointerInSchema(pointer, ctx.mote, this);
50
+ if (!subschema) {
51
+ console.warn(`Could not resolve pointer ${pointer.join('/')} for schema ${ctx.mote.schema_id}`);
52
+ continue;
53
+ }
54
+ const newCtx = {
55
+ ...ctx,
56
+ current: {
57
+ data: data[key],
58
+ key,
59
+ pointer,
60
+ subschema,
61
+ },
62
+ parent: ctx.current,
63
+ };
64
+ visit(newCtx);
65
+ }
66
+ }
67
+ };
68
+ visit(initialCtx);
69
+ }
70
+ getAncestors(ofMoteId, options) {
71
+ const mote = this.getMote(ofMoteId);
72
+ assert(mote, `Cannot get parents: mote not found ${ofMoteId}`);
73
+ const hierarchy = [];
74
+ let parent = this.getMote(mote.parent);
75
+ const seen = new Set();
76
+ while (parent) {
77
+ hierarchy.push(parent);
78
+ parent = this.getMote(parent.parent);
79
+ // Prevent infinite loops
80
+ if (parent && seen.has(parent.id)) {
81
+ if (options?.ignoreCircularity)
82
+ break;
83
+ throw new Error(`Mote ${parent.id} is in a circular hierarchy!`);
84
+ }
85
+ else if (parent) {
86
+ seen.add(parent.id);
87
+ }
88
+ }
89
+ return hierarchy.reverse();
90
+ }
91
+ getMoteNamePointer(mote) {
92
+ if (!mote)
93
+ return undefined;
94
+ const foundMote = this.getMote(mote);
95
+ if (!foundMote)
96
+ return undefined;
97
+ const schema = this.getSchema(foundMote.schema_id);
98
+ return schema?.name;
99
+ }
100
+ getMoteName(moteId) {
101
+ const pointer = this.getMoteNamePointer(moteId);
102
+ const mote = this.getMote(moteId);
103
+ if (!pointer || !mote) {
104
+ return mote?.id;
105
+ }
106
+ return resolvePointer(pointer, mote.data) || mote.id;
107
+ }
108
+ getMote(moteId) {
109
+ if (!moteId)
110
+ return;
111
+ return this.data.motes[typeof moteId === 'string' ? moteId : moteId.id];
112
+ }
113
+ getSchema(schemaId) {
114
+ if (!schemaId)
115
+ return;
116
+ return this.data.schemas[schemaId];
117
+ }
118
+ listMotes() {
119
+ return Object.values(this.data.motes);
120
+ }
121
+ listMotesBySchema(...schemaId) {
122
+ return Object.values(this.data.motes).filter((mote) => schemaId.includes(mote.schema_id));
123
+ }
124
+ static async from(gcdataFile) {
125
+ const data = JSON.parse(await gcdataFile.read({ parse: false }));
126
+ return new Gcdata(data);
127
+ }
128
+ }
129
+ export class GameChanger {
130
+ projectName;
131
+ base;
132
+ working;
133
+ changes;
134
+ #spellChecker;
135
+ constructor(projectName) {
136
+ this.projectName = projectName;
137
+ }
138
+ get spellChecker() {
139
+ // Lazy-load the spell checker to save some compute
140
+ this.#spellChecker ||= new SpellChecker(this);
141
+ return this.#spellChecker;
142
+ }
143
+ get workingData() {
144
+ return this.working.data;
145
+ }
146
+ get baseData() {
147
+ return this.base.data;
148
+ }
149
+ get projectSaveDir() {
150
+ return GameChanger.projectSaveDir(this.projectName);
151
+ }
152
+ clearMoteChanges(moteId) {
153
+ delete this.changes.changes.motes?.[moteId];
154
+ // Re-clone the base data to reset the working data
155
+ delete this.working.data.motes[moteId];
156
+ if (this.base.data.motes[moteId]) {
157
+ this.working.data.motes[moteId] = structuredClone(this.base.data.motes[moteId]);
158
+ }
159
+ }
160
+ updateMoteLocation(moteId, newParentId, newFolder) {
161
+ assert(moteId && typeof moteId === 'string', 'Must specify mote ID');
162
+ assert(newParentId === undefined || typeof newParentId === 'string', 'Parent ID must be a string or undefined');
163
+ assert(newFolder === undefined ||
164
+ (typeof newFolder === 'string' && newFolder.length > 0), 'Folder must be a string or undefined');
165
+ const mote = this.working.getMote(moteId);
166
+ assert(mote, `Cannot update non-existent mote ${moteId}`);
167
+ const parent = newParentId ? this.working.getMote(newParentId) : undefined;
168
+ assert(parent || newParentId === undefined, `Cannot find mote ${newParentId}`);
169
+ setValueAtPointer(this.working.data.motes[moteId], 'parent', parent?.id);
170
+ setValueAtPointer(this.working.data.motes[moteId], 'folder', newFolder);
171
+ // See if we have a change relative to the base
172
+ const baseMote = this.base.getMote(moteId);
173
+ const baseParent = baseMote?.parent;
174
+ let changedParent = baseParent !== parent?.id;
175
+ let changedFolder = baseMote?.folder !== newFolder;
176
+ if (!changedParent) {
177
+ // Then we haven't changed from the base data, but
178
+ // we might be *undoing* a working data change.
179
+ delete this.changes.changes.motes?.[moteId]?.diffs?.parent;
180
+ }
181
+ else {
182
+ this.createChange('motes', moteId, {
183
+ type: 'changed',
184
+ pointer: 'parent',
185
+ newValue: parent?.id,
186
+ });
187
+ }
188
+ if (!changedFolder) {
189
+ delete this.changes.changes.motes?.[moteId]?.diffs?.folder;
190
+ }
191
+ else {
192
+ this.createChange('motes', moteId, {
193
+ type: 'changed',
194
+ pointer: 'folder',
195
+ newValue: newFolder,
196
+ });
197
+ }
198
+ }
199
+ updateMoteData(moteId, dataPath, value) {
200
+ assert(moteId, 'Must specify mote ID');
201
+ assert(typeof dataPath === 'string' && dataPath.startsWith('data/'), 'Data path must start with "data/"');
202
+ // Make sure this is a valid request
203
+ const workingMote = this.working.getMote(moteId);
204
+ assert(workingMote, `Cannot update non-existent mote ${moteId}`);
205
+ const schema = this.working.getSchema(workingMote.schema_id);
206
+ assert(schema, `Mote schema ${workingMote.schema_id} does not exist`);
207
+ // // Need a data structure that can be used for reference
208
+ // // when resolving schema pointers, to handle oneOfs.
209
+ const sampleDataFromPath = setValueAtPointer({
210
+ id: moteId,
211
+ schema_id: this.working.getMote(moteId)?.schema_id,
212
+ data: {},
213
+ }, dataPath, value);
214
+ const subschema = resolvePointerInSchema(dataPath.replace(/^data\//, ''), workingMote, this.working, sampleDataFromPath);
215
+ assert(subschema, `Could not resolve ${dataPath} in schema ${workingMote.schema_id}}`);
216
+ // Do some basic schema validation to avoid really dumb errors
217
+ if (isBschemaConst(subschema)) {
218
+ assert(value === null || value === subschema.bConst, `Expected constant value ${JSON.stringify(subschema.bConst)}, got ${JSON.stringify(value)}`);
219
+ }
220
+ else if (isBschemaEnum(subschema)) {
221
+ assert(subschema.enum.includes(value), `'${value}' is not in enum ${JSON.stringify(subschema.enum)}`);
222
+ }
223
+ else if (typeof value === 'string') {
224
+ assert(isBschemaString(subschema), `Invalid value '${JSON.stringify(value)}'. Schema for ${dataPath} is not for a string.`);
225
+ }
226
+ else if (typeof value === 'boolean') {
227
+ assert(isBschemaBoolean(subschema), `Invalid value '${JSON.stringify(value)}'. Schema for ${dataPath} is not boolean`);
228
+ }
229
+ else if (typeof value === 'number') {
230
+ assert(isBschemaBoolean(subschema) || isBschemaNumeric(subschema), `Invalid value '${JSON.stringify(value)}'. Schema for ${dataPath} is not numeric`);
231
+ }
232
+ if (isBschemaObject(subschema) && value === null) {
233
+ // Then we are deleting a sub-object, so we need to find each
234
+ // entry by path and add a deletion for it
235
+ const subdata = resolvePointer(dataPath, this.workingData.motes[moteId]);
236
+ const pointers = computeTerminalPointers(subdata, dataPath);
237
+ for (const pointer of pointers) {
238
+ this.updateMoteData(moteId, pointer, null);
239
+ }
240
+ // We don't store the deletion of the sub-object itself, so we're done!
241
+ return;
242
+ }
243
+ // Update the working data
244
+ setValueAtPointer(this.working.data.motes[moteId], dataPath, value);
245
+ // See if we have a change relative to the base
246
+ const currentValue = resolvePointer(dataPath, this.base.getMote(moteId)) ??
247
+ (subschema.defaultValue === undefined
248
+ ? null
249
+ : structuredClone(subschema.defaultValue));
250
+ value = value ?? null;
251
+ if (currentValue == value) {
252
+ // Then we haven't changed from the base data, but
253
+ // we might be *undoing* a working data change.
254
+ delete this.changes.changes.motes?.[moteId]?.diffs?.[dataPath];
255
+ return;
256
+ }
257
+ this.createChange('motes', moteId, {
258
+ type: 'changed',
259
+ pointer: dataPath,
260
+ newValue: value,
261
+ });
262
+ }
263
+ createChange(category, id, change) {
264
+ const moteId = category === 'motes' ? id : undefined;
265
+ assert(moteId || category === 'schemas', 'Must specify mote ID for mote changes');
266
+ const mote = moteId
267
+ ? this.working.getMote(moteId) || change.newValue
268
+ : undefined;
269
+ const schemaId = category === 'schemas' ? id : mote?.schema_id;
270
+ assert(schemaId, 'Could not determine schema ID for change');
271
+ assert(!moteId || this.working.getMote(moteId) || change.type === 'added', `Mote ${id} does not exist`);
272
+ if (category === 'motes' && change.type === 'added') {
273
+ assert(!this.working.getMote(moteId), `Mote ${moteId} already exists`);
274
+ }
275
+ if (category === 'schemas' && change.type === 'added') {
276
+ assert(!this.working.getSchema(schemaId), `Schema ${schemaId} already exists`);
277
+ }
278
+ assert((category === 'schemas' && change.type === 'added') ||
279
+ this.working.getSchema(schemaId), `Schema ${schemaId} does not exist`);
280
+ this.changes.changes[category] ||= {};
281
+ const item = changeSchema.parse(this.changes.changes[category]?.[id] || {
282
+ mote_id: moteId,
283
+ schema_id: schemaId,
284
+ type: change.type,
285
+ });
286
+ item.mote_name ||= this.working.getMoteName(moteId);
287
+ this.changes.changes[category][id] = item;
288
+ if (change.type === 'deleted') {
289
+ item.type = 'deleted';
290
+ delete item.diffs;
291
+ }
292
+ else if (change.pointer) {
293
+ let originalValue = resolvePointer(change.pointer, this.baseData[category][id]);
294
+ originalValue = originalValue === undefined ? null : originalValue;
295
+ change.newValue = change.newValue === undefined ? null : change.newValue;
296
+ if (originalValue !== change.newValue) {
297
+ item.diffs ||= {};
298
+ item.diffs[change.pointer] = [originalValue, change.newValue];
299
+ }
300
+ }
301
+ this.applyChanges();
302
+ gameChangerEvents.emit('gamechanger-working-updated', mote);
303
+ }
304
+ async writeChanges() {
305
+ // Write it to a backup file first (to ensure that the GameChanger)
306
+ // doesn't clobber what we've done without a recovery option.
307
+ // Then write it to the actual file.
308
+ const backupsFolder = GameChanger.projectGameChangerChangesBackupFolder(this.projectName);
309
+ await backupsFolder.ensureDirectory();
310
+ const changesFile = GameChanger.projectGameChangerChangesFile(this.projectName);
311
+ if (await changesFile.exists()) {
312
+ // Copy it to the backup folder
313
+ const now = new Date();
314
+ const parts = [
315
+ now.getFullYear(),
316
+ now.getMonth() + 1,
317
+ now.getDate(),
318
+ now.getHours(),
319
+ now.getMinutes(),
320
+ now.getSeconds(),
321
+ ].map((n) => n.toString().padStart(2, '0'));
322
+ const timestamp = parts.join('');
323
+ const backupFile = backupsFolder.join(`${timestamp}.changes.json`);
324
+ await changesFile.copy(backupFile);
325
+ }
326
+ await GameChanger.projectGameChangerChangesFile(this.projectName).write(this.changes);
327
+ gameChangerEvents.emit('gamechanger-changes-saved');
328
+ }
329
+ /** Apply changes to the baseData to get the updated workingData */
330
+ applyChanges() {
331
+ assert(this.changes.commitId === this.baseData.commitId, 'The changes and base data have different commit IDs');
332
+ // Apply changes
333
+ for (const type of ['motes', 'schemas']) {
334
+ const ids = Object.keys(this.changes.changes[type]);
335
+ for (const id of ids) {
336
+ const change = this.changes.changes[type][id];
337
+ if (change.type === 'deleted') {
338
+ delete this.workingData[type][id];
339
+ continue;
340
+ }
341
+ else if (change.type === 'changed' &&
342
+ !Object.keys(change.diffs || {}).length) {
343
+ // Then we can remove this change entry altogether
344
+ delete this.changes.changes[type][id];
345
+ continue;
346
+ }
347
+ // Ensure the base object exists
348
+ this.workingData[type][id] ||= {};
349
+ for (const [pointer, diff] of Object.entries(change.diffs || {})) {
350
+ let data = this.workingData[type][id];
351
+ const dataPath = [{ data, key: undefined }];
352
+ const pointerParts = pointer.split('/');
353
+ for (let p = 0; p < pointerParts.length; p++) {
354
+ const part = pointerParts[p];
355
+ const isLastPart = p === pointerParts.length - 1;
356
+ if (isLastPart) {
357
+ data[part] = diff[1];
358
+ }
359
+ else {
360
+ data[part] ||= {};
361
+ }
362
+ data = data[part];
363
+ dataPath.push({ data, key: part });
364
+ }
365
+ // Work backwards through the data, deleting it if it is empty
366
+ // (except for the root!)
367
+ for (let p = dataPath.length - 1; p > 0; p--) {
368
+ const part = dataPath[p];
369
+ // If the entry is `null`, `undefined`, or an empty object, delete it. Else break.
370
+ if (part.data === undefined ||
371
+ part.data === null ||
372
+ Object.keys(part.data).length === 0) {
373
+ const parent = dataPath[p - 1].data;
374
+ delete parent[part.key];
375
+ }
376
+ else
377
+ break;
378
+ }
379
+ }
380
+ }
381
+ }
382
+ }
383
+ async loadChanges() {
384
+ const changesFile = GameChanger.projectGameChangerChangesFile(this.projectName);
385
+ if (!(await changesFile.exists())) {
386
+ const metadata = await this.readCommitsMetadata();
387
+ // Get the commitIds, sorted descending by number
388
+ const commitIds = Object.keys(metadata.item_metadata)
389
+ .map((itemId) => metadata.item_metadata[itemId].name)
390
+ .sort((a, b) => {
391
+ const aNum = parseInt(a.replace(/^c/, ''));
392
+ const bNum = parseInt(b.replace(/^c/, ''));
393
+ return bNum - aNum;
394
+ });
395
+ assert(commitIds.length, 'No commits found. Open the GameChanger to download the latest commit.');
396
+ const initial = {
397
+ changes: {
398
+ message: '',
399
+ motes: {},
400
+ schemas: {},
401
+ conflicts: { motes: {}, schemas: {} },
402
+ },
403
+ commitId: commitIds[0],
404
+ };
405
+ await changesFile.write(initial);
406
+ }
407
+ this.changes = await changesFile.read();
408
+ }
409
+ async readCommitsMetadata() {
410
+ const metadataFile = GameChanger.projectRumpusGameChangerMetadataFile(this.projectName);
411
+ assert(await metadataFile.exists(), 'Could not find game-changer metadata file. Open the GameChanger to ensure that it gets created.');
412
+ // Consists of 3 lines. The first one is the JSON we want.
413
+ const content = (await metadataFile.read({
414
+ parse: false,
415
+ }));
416
+ const [rawMetadata] = content.split('\n');
417
+ assert(rawMetadata, 'Metadata file malformed.');
418
+ try {
419
+ return gameChangerRumpusMetadataSchema.parse(JSON.parse(rawMetadata));
420
+ }
421
+ catch (err) {
422
+ const issue = new GcdataError('Could not parse game-changer metadata file.');
423
+ issue.cause = err;
424
+ throw err;
425
+ }
426
+ }
427
+ async load() {
428
+ await this.loadChanges();
429
+ const metadata = await this.readCommitsMetadata();
430
+ // Use the game-changer metadata file to find the base game-changer data
431
+ const commitItemId = Object.keys(metadata.item_metadata).find((itemId) => metadata.item_metadata[itemId].name === this.changes.commitId);
432
+ assert(commitItemId, `Could not find commit item with name "${this.changes.commitId}"`);
433
+ const commitItemFile = GameChanger.projectRumpusGameChangerDir(this.projectName).join(commitItemId);
434
+ assert(await commitItemFile.exists(), `Could not find commit item file "${commitItemFile}"`);
435
+ const baseData = JSON.parse(await commitItemFile.read({ parse: false }));
436
+ this.base ||= new Gcdata(baseData);
437
+ this.base.data = baseData;
438
+ const workingData = structuredClone(baseData);
439
+ this.working ||= new Gcdata(workingData);
440
+ this.working.data = workingData;
441
+ this.applyChanges();
442
+ }
443
+ /**
444
+ * @param path Either the path to a .yyp file (to get the included packed file) or the direct path to a GameChanger snapshot (e.g. a packed file or a base file).
445
+ */
446
+ static async from(projectName) {
447
+ const gcdata = new GameChanger(projectName);
448
+ try {
449
+ await gcdata.load();
450
+ return gcdata;
451
+ }
452
+ catch (err) {
453
+ console.error(err);
454
+ return undefined;
455
+ }
456
+ }
457
+ static projectSaveDir(projectName) {
458
+ return pathy(`${process.env.LOCALAPPDATA}/${projectName}`);
459
+ }
460
+ static projectRumpusGameChangerDir(projectName) {
461
+ return this.projectSaveDir(projectName).join('Dev/Rumpus/Crates/game-changer');
462
+ }
463
+ static projectRumpusGameChangerMetadataFile(projectName) {
464
+ return this.projectRumpusGameChangerDir(projectName).join('metadata');
465
+ }
466
+ static projectGameChangerChangesFile(projectName) {
467
+ return this.projectGameChangerChangesFolder(projectName)
468
+ .join('changes.json')
469
+ .withValidator(changesSchema);
470
+ }
471
+ static projectGameChangerChangesFolder(projectName) {
472
+ return this.projectSaveDir(projectName).join('gcdata');
473
+ }
474
+ static projectGameChangerChangesBackupFolder(projectName) {
475
+ return this.projectGameChangerChangesFolder(projectName).join('stitch-backups');
476
+ }
477
+ }
478
+ //# sourceMappingURL=GameChanger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GameChanger.js","sourceRoot":"","sources":["../src/GameChanger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import nspell from 'nspell';
2
+ import type { GameChanger } from './GameChanger.js';
3
+ import { ParsedLineItem } from './cl2.quest.types.js';
4
+ export declare class SpellChecker {
5
+ readonly gameChanger: GameChanger;
6
+ protected options: {
7
+ /** Motes with these schema IDs will not have their names added to the dictionary */
8
+ skipSchemas?: string[];
9
+ };
10
+ protected checker: nspell;
11
+ constructor(gameChanger: GameChanger, options?: {
12
+ /** Motes with these schema IDs will not have their names added to the dictionary */
13
+ skipSchemas?: string[];
14
+ });
15
+ checkWord(word: ParsedLineItem): {
16
+ valid: boolean;
17
+ start: import("./types.editor.js").Position;
18
+ end: import("./types.editor.js").Position;
19
+ value: string;
20
+ };
21
+ check(text: ParsedLineItem): {
22
+ valid: boolean;
23
+ start: import("./types.editor.js").Position;
24
+ end: import("./types.editor.js").Position;
25
+ value: string;
26
+ }[];
27
+ reload(): void;
28
+ /** Get the list of localized Mote Names, broken into "words" for use in the dictionary. */
29
+ protected listMoteNameWords(): string[];
30
+ }
31
+ //# sourceMappingURL=SpellChecker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpellChecker.d.ts","sourceRoot":"","sources":["../src/SpellChecker.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD,qBAAa,YAAY;aAIL,WAAW,EAAE,WAAW;IACxC,SAAS,CAAC,OAAO,EAAE;QACjB,oFAAoF;QACpF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB;IAPH,SAAS,CAAC,OAAO,SAA8C;gBAG7C,WAAW,EAAE,WAAW,EAC9B,OAAO,GAAE;QACjB,oFAAoF;QACpF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB;IAOR,SAAS,CAAC,IAAI,EAAE,cAAc;;;;;;IAuB9B,KAAK,CAAC,IAAI,EAAE,cAAc;;;;;;IAK1B,MAAM;IAMN,2FAA2F;IAC3F,SAAS,CAAC,iBAAiB;CAsD5B"}
@@ -0,0 +1,92 @@
1
+ import nspell from 'nspell';
2
+ import { aff, dic } from './dict.js';
3
+ import { normalizePointer, parsedItemToWords, resolvePointerInSchema, } from './util.js';
4
+ export class SpellChecker {
5
+ gameChanger;
6
+ options;
7
+ checker = nspell(Buffer.from(aff), Buffer.from(dic));
8
+ constructor(gameChanger, options = {}) {
9
+ this.gameChanger = gameChanger;
10
+ this.options = options;
11
+ this.reload();
12
+ // // NOTE: This is pretty expensive since it rebuilds the whole dictionary.
13
+ // gameChangerEvents.on('gamechanger-changes-saved', () => this.reload());
14
+ }
15
+ checkWord(word) {
16
+ let value = word.value;
17
+ if (value.match(/in'$/)) {
18
+ // Then it's a Tendraam-style contraction
19
+ value = value.replace(/in'$/, 'ing');
20
+ }
21
+ if (value.match(/'s$/)) {
22
+ // Probably an intentional possessive of something.
23
+ value = value.replace(/'s$/, '');
24
+ }
25
+ if (value.match(/s$/) && !this.checker.correct(value)) {
26
+ // Probably a simple plural
27
+ value = value.replace(/s$/, '');
28
+ }
29
+ const valid = this.checker.correct(value);
30
+ return {
31
+ ...word,
32
+ valid,
33
+ // // NOTE: Suggestions are costly to compute, should do it on demand
34
+ // suggestions: valid ? undefined : this.checker.suggest(value),
35
+ };
36
+ }
37
+ check(text) {
38
+ // Split the text into words
39
+ return parsedItemToWords(text).map((w) => this.checkWord(w));
40
+ }
41
+ reload() {
42
+ this.checker = nspell(Buffer.from(aff), Buffer.from(dic));
43
+ const words = this.listMoteNameWords();
44
+ this.checker.personal(words.join('\n'));
45
+ }
46
+ /** Get the list of localized Mote Names, broken into "words" for use in the dictionary. */
47
+ listMoteNameWords() {
48
+ const names = [];
49
+ // Find all mote names that are meant to be localized, and
50
+ // add those names to the spell checker.
51
+ const motes = this.gameChanger.working.listMotes();
52
+ for (const mote of motes) {
53
+ if (this.options.skipSchemas?.includes(mote.schema_id))
54
+ continue;
55
+ const schema = this.gameChanger.working.getSchema(mote.schema_id);
56
+ const namePointer = schema?.name;
57
+ if (!schema || !namePointer)
58
+ continue;
59
+ // Need to check one level up to see if this is an L10n field.
60
+ const parentPointer = normalizePointer(namePointer);
61
+ parentPointer.pop();
62
+ const nameSchema = resolvePointerInSchema(parentPointer, mote, this.gameChanger.working);
63
+ if (nameSchema &&
64
+ 'format' in nameSchema &&
65
+ nameSchema.format === 'l10n' &&
66
+ !mote.data.wip?.draft) {
67
+ names.push(this.gameChanger.working.getMoteName(mote.id));
68
+ }
69
+ }
70
+ const words = new Set();
71
+ for (const name of names) {
72
+ const parts = name.trim().split(/\s+/g);
73
+ for (let part of parts) {
74
+ // Remove any apostrophes
75
+ part = part.replace(/'.*/g, '');
76
+ // Remove any trailing punctuation
77
+ part = part.replace(/\s*[!?)\]-]+$/g, '');
78
+ // Remove any leading punctuation
79
+ part = part.replace(/^[!?([-]+\s*/g, '');
80
+ const skip = part.length < 2 ||
81
+ part.match(/^\d+|\d+x\d+|.*\/.*$/) ||
82
+ this.checker.correct(part);
83
+ if (!skip) {
84
+ words.add(part);
85
+ }
86
+ }
87
+ }
88
+ // Sort by lower-case
89
+ return [...words].sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
90
+ }
91
+ }
92
+ //# sourceMappingURL=SpellChecker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpellChecker.js","sourceRoot":"","sources":["../src/SpellChecker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare class GcdataError extends Error {
2
+ constructor(message: string, asserter?: Function);
3
+ }
4
+ export declare function assert(claim: any, message: string): asserts claim;
5
+ export declare function assertThrows(fn: Function, message: string): void;
6
+ //# sourceMappingURL=assert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../src/assert.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;CAKjD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAIjE;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAOhE"}