@patterkit/core 0.2.0 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
@@ -36,59 +26,35 @@ __export(index_exports, {
36
26
  hash32: () => hash32,
37
27
  hash4: () => hash4,
38
28
  isValidGameId: () => import_model4.isValidGameId,
39
- newId: () => newId,
40
- parseSource: () => parseSource,
29
+ newId: () => import_toolkit.newId,
30
+ parseSource: () => import_toolkit3.parseSource,
41
31
  slug: () => slug,
42
32
  validateProject: () => validateProject
43
33
  });
44
34
  module.exports = __toCommonJS(index_exports);
45
35
 
46
36
  // src/ids.ts
47
- var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
48
- function newId(prefix = "", length = 8) {
49
- const limit = 256 - 256 % ALPHABET.length;
50
- let token = "";
51
- while (token.length < length) {
52
- const bytes = new Uint8Array(length * 2);
53
- globalThis.crypto.getRandomValues(bytes);
54
- for (const b of bytes) {
55
- if (b >= limit) continue;
56
- token += ALPHABET[b % ALPHABET.length];
57
- if (token.length === length) break;
58
- }
59
- }
60
- return prefix ? `${prefix}_${token}` : token;
61
- }
37
+ var import_toolkit = require("@wildwinter/toolkit");
62
38
 
63
39
  // src/handle.ts
40
+ var import_toolkit2 = require("@wildwinter/toolkit");
64
41
  function slug(name) {
65
42
  const s = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
66
43
  return s || "_";
67
44
  }
68
- function fnv32(input) {
69
- let h = 2166136261;
70
- for (let i = 0; i < input.length; i++) {
71
- h ^= input.charCodeAt(i);
72
- h = Math.imul(h, 16777619);
73
- }
74
- return h >>> 0;
75
- }
76
45
  function hash4(input) {
77
- return fnv32(input).toString(36).slice(-4).padStart(4, "0");
46
+ return (0, import_toolkit2.fnv32)(input).toString(36).slice(-4).padStart(4, "0");
78
47
  }
79
48
  function hash32(input) {
80
- return fnv32(input).toString(36).padStart(7, "0");
49
+ return (0, import_toolkit2.fnv32)(input).toString(36).padStart(7, "0");
81
50
  }
82
51
 
83
52
  // src/index.ts
84
53
  var import_model4 = require("@patterkit/model");
85
54
 
86
55
  // src/serialize.ts
87
- var import_json5 = __toESM(require("json5"), 1);
88
- function parseSource(text) {
89
- const body = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
90
- return import_json5.default.parse(body);
91
- }
56
+ var import_json5 = require("json5");
57
+ var import_toolkit3 = require("@wildwinter/toolkit");
92
58
  function canonicalStringify(value, opts) {
93
59
  return write(value, "", opts?.trailingComma ?? true) + "\n";
94
60
  }
@@ -460,6 +426,21 @@ function checkDecls(decls, where, issues) {
460
426
  message: `${where}: '${decl.name}' is ${decl.type} but declares no values`
461
427
  });
462
428
  }
429
+ if (decl.type === "quality") {
430
+ const stages = decl.stages ?? [];
431
+ if (stages.length < 2) {
432
+ issues.push({
433
+ code: "invalid-declaration",
434
+ message: `${where}: '${decl.name}' is a quality but declares ${stages.length === 0 ? "no stages" : "only one stage"} (a ladder needs at least two)`
435
+ });
436
+ }
437
+ const seenStages = /* @__PURE__ */ new Set();
438
+ for (const s of stages) {
439
+ if (!s.trim()) issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' has an empty stage name` });
440
+ else if (seenStages.has(s)) issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' declares stage '${s}' more than once` });
441
+ else seenStages.add(s);
442
+ }
443
+ }
463
444
  if (decl.default !== void 0 && !defaultMatchesType(decl.default, decl)) {
464
445
  issues.push({
465
446
  code: "invalid-declaration",
@@ -480,6 +461,8 @@ function defaultMatchesType(value, decl) {
480
461
  return typeof value === "string" && (decl.values?.includes(value) ?? true);
481
462
  case "flags":
482
463
  return Array.isArray(value) && value.every((v) => typeof v === "string" && (decl.values?.includes(v) ?? true));
464
+ case "quality":
465
+ return typeof value === "string" && (decl.stages?.includes(value) ?? true);
483
466
  }
484
467
  }
485
468
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.d.cts CHANGED
@@ -1,9 +1,7 @@
1
+ export { newId, parseSource } from '@wildwinter/toolkit';
1
2
  import { ProjectFile, Scene, AuthoringFile } from '@patterkit/model';
2
3
  export { effectiveGameId, gameIdify, isValidGameId } from '@patterkit/model';
3
4
 
4
- /** Generate a new opaque id, e.g. `newId("scn") -> "scn_8f3kq2z1"`. */
5
- declare function newId(prefix?: string, length?: number): string;
6
-
7
5
  /** Slugify an author name into a filename- / address-safe segment. */
8
6
  declare function slug(name: string): string;
9
7
  /** Deterministic 4-char base-36 hash of a string (FNV-1a 32-bit). */
@@ -11,8 +9,6 @@ declare function hash4(input: string): string;
11
9
  /** Deterministic 7-char base-36 hash of a string (full FNV-1a 32-bit width) - e.g. content hashes. */
12
10
  declare function hash32(input: string): string;
13
11
 
14
- /** Parse JSON5 source text (a leading BOM is tolerated). Throws on malformed input. */
15
- declare function parseSource(text: string): unknown;
16
12
  /** Options for {@link canonicalStringify}. */
17
13
  interface StringifyOptions {
18
14
  /** Emit a trailing comma after the last item/entry (the canonical SOURCE form).
@@ -37,4 +33,4 @@ interface ProjectInput {
37
33
  /** Validate a project's structural invariants. Returns an empty array when valid. */
38
34
  declare function validateProject(input: ProjectInput): ValidationIssue[];
39
35
 
40
- export { type ProjectInput, type StringifyOptions, type ValidationIssue, canonicalStringify, hash32, hash4, newId, parseSource, slug, validateProject };
36
+ export { type ProjectInput, type StringifyOptions, type ValidationIssue, canonicalStringify, hash32, hash4, slug, validateProject };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
+ export { newId, parseSource } from '@wildwinter/toolkit';
1
2
  import { ProjectFile, Scene, AuthoringFile } from '@patterkit/model';
2
3
  export { effectiveGameId, gameIdify, isValidGameId } from '@patterkit/model';
3
4
 
4
- /** Generate a new opaque id, e.g. `newId("scn") -> "scn_8f3kq2z1"`. */
5
- declare function newId(prefix?: string, length?: number): string;
6
-
7
5
  /** Slugify an author name into a filename- / address-safe segment. */
8
6
  declare function slug(name: string): string;
9
7
  /** Deterministic 4-char base-36 hash of a string (FNV-1a 32-bit). */
@@ -11,8 +9,6 @@ declare function hash4(input: string): string;
11
9
  /** Deterministic 7-char base-36 hash of a string (full FNV-1a 32-bit width) - e.g. content hashes. */
12
10
  declare function hash32(input: string): string;
13
11
 
14
- /** Parse JSON5 source text (a leading BOM is tolerated). Throws on malformed input. */
15
- declare function parseSource(text: string): unknown;
16
12
  /** Options for {@link canonicalStringify}. */
17
13
  interface StringifyOptions {
18
14
  /** Emit a trailing comma after the last item/entry (the canonical SOURCE form).
@@ -37,4 +33,4 @@ interface ProjectInput {
37
33
  /** Validate a project's structural invariants. Returns an empty array when valid. */
38
34
  declare function validateProject(input: ProjectInput): ValidationIssue[];
39
35
 
40
- export { type ProjectInput, type StringifyOptions, type ValidationIssue, canonicalStringify, hash32, hash4, newId, parseSource, slug, validateProject };
36
+ export { type ProjectInput, type StringifyOptions, type ValidationIssue, canonicalStringify, hash32, hash4, slug, validateProject };
package/dist/index.js CHANGED
@@ -1,33 +1,12 @@
1
1
  // src/ids.ts
2
- var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
3
- function newId(prefix = "", length = 8) {
4
- const limit = 256 - 256 % ALPHABET.length;
5
- let token = "";
6
- while (token.length < length) {
7
- const bytes = new Uint8Array(length * 2);
8
- globalThis.crypto.getRandomValues(bytes);
9
- for (const b of bytes) {
10
- if (b >= limit) continue;
11
- token += ALPHABET[b % ALPHABET.length];
12
- if (token.length === length) break;
13
- }
14
- }
15
- return prefix ? `${prefix}_${token}` : token;
16
- }
2
+ import { newId } from "@wildwinter/toolkit";
17
3
 
18
4
  // src/handle.ts
5
+ import { fnv32 } from "@wildwinter/toolkit";
19
6
  function slug(name) {
20
7
  const s = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
21
8
  return s || "_";
22
9
  }
23
- function fnv32(input) {
24
- let h = 2166136261;
25
- for (let i = 0; i < input.length; i++) {
26
- h ^= input.charCodeAt(i);
27
- h = Math.imul(h, 16777619);
28
- }
29
- return h >>> 0;
30
- }
31
10
  function hash4(input) {
32
11
  return fnv32(input).toString(36).slice(-4).padStart(4, "0");
33
12
  }
@@ -39,11 +18,8 @@ function hash32(input) {
39
18
  import { gameIdify, isValidGameId as isValidGameId2, effectiveGameId as effectiveGameId2 } from "@patterkit/model";
40
19
 
41
20
  // src/serialize.ts
42
- import JSON5 from "json5";
43
- function parseSource(text) {
44
- const body = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
45
- return JSON5.parse(body);
46
- }
21
+ import "json5";
22
+ import { parseSource } from "@wildwinter/toolkit";
47
23
  function canonicalStringify(value, opts) {
48
24
  return write(value, "", opts?.trailingComma ?? true) + "\n";
49
25
  }
@@ -415,6 +391,21 @@ function checkDecls(decls, where, issues) {
415
391
  message: `${where}: '${decl.name}' is ${decl.type} but declares no values`
416
392
  });
417
393
  }
394
+ if (decl.type === "quality") {
395
+ const stages = decl.stages ?? [];
396
+ if (stages.length < 2) {
397
+ issues.push({
398
+ code: "invalid-declaration",
399
+ message: `${where}: '${decl.name}' is a quality but declares ${stages.length === 0 ? "no stages" : "only one stage"} (a ladder needs at least two)`
400
+ });
401
+ }
402
+ const seenStages = /* @__PURE__ */ new Set();
403
+ for (const s of stages) {
404
+ if (!s.trim()) issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' has an empty stage name` });
405
+ else if (seenStages.has(s)) issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' declares stage '${s}' more than once` });
406
+ else seenStages.add(s);
407
+ }
408
+ }
418
409
  if (decl.default !== void 0 && !defaultMatchesType(decl.default, decl)) {
419
410
  issues.push({
420
411
  code: "invalid-declaration",
@@ -435,6 +426,8 @@ function defaultMatchesType(value, decl) {
435
426
  return typeof value === "string" && (decl.values?.includes(value) ?? true);
436
427
  case "flags":
437
428
  return Array.isArray(value) && value.every((v) => typeof v === "string" && (decl.values?.includes(v) ?? true));
429
+ case "quality":
430
+ return typeof value === "string" && (decl.stages?.includes(value) ?? true);
438
431
  }
439
432
  }
440
433
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/core",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Patter core: stable id generation, readable-handle computation, canonical (de)serialisation, and the structural validator.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,7 +34,8 @@
34
34
  "build": "tsup src/index.ts --format esm,cjs --dts --clean"
35
35
  },
36
36
  "dependencies": {
37
- "@patterkit/model": "0.3.0",
37
+ "@patterkit/model": "0.4.1",
38
+ "@wildwinter/toolkit": "^0.1.0",
38
39
  "json5": "^2.2.3"
39
40
  }
40
41
  }