@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 +25 -42
- package/dist/index.d.cts +2 -6
- package/dist/index.d.ts +2 -6
- package/dist/index.js +21 -28
- package/package.json +3 -2
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
|
|
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 =
|
|
88
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
|
43
|
-
|
|
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.
|
|
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.
|
|
37
|
+
"@patterkit/model": "0.4.1",
|
|
38
|
+
"@wildwinter/toolkit": "^0.1.0",
|
|
38
39
|
"json5": "^2.2.3"
|
|
39
40
|
}
|
|
40
41
|
}
|