@kubohiroya/turbowarp-structured-data 0.6.0 → 0.6.1
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/README.ja.md +13 -0
- package/README.md +14 -1
- package/dist/structured-data.js +342 -148
- package/docs/index.html +1 -1
- package/docs/schemas/block-editor-fixed-inputs.schema.json +20 -0
- package/package.json +15 -8
- package/schemas/block-editor-fixed-inputs.schema.json +20 -0
- package/src/extension.ts +29 -4
- package/src/fixed-input-editors.ts +67 -0
- package/src/fixed-input-schema.ts +16 -0
- package/templates/README.ja.md +13 -0
- package/templates/README.md +13 -0
package/README.ja.md
CHANGED
|
@@ -71,3 +71,16 @@ pnpm run check
|
|
|
71
71
|
SPDX-License-Identifier: MPL-2.0
|
|
72
72
|
|
|
73
73
|
bundleへ含まれるthird-party softwareのlicenseは[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)に記載します。
|
|
74
|
+
|
|
75
|
+
## 固定引数の編集フォーム(S3-4)
|
|
76
|
+
|
|
77
|
+
共通エディターの起動時フラグ `blockEditorFixedInputs` とDialogsがONのGUIでは、`forEachAtPath` の `MAX` だけを固定フォームとして登録します。旧GUI・フラグOFFでは追加登録を行いません。Schemaの正本は `schemas/block-editor-fixed-inputs.schema.json#/$defs/forEachAtPath/properties/MAX`、codecと登録は `src/fixed-input-editors.ts` です。既存raw値・未変更alias・未知enumは無操作保存で書き換えず、reporterを評価しません。明示変更だけを検査し、他の引数やブロック宣言、保存形式を変更しません。
|
|
78
|
+
|
|
79
|
+
MAXは整数1〜1000です。新しい入力には共通の有限数値token規則も適用し、途中入力を保存しません。MVP flagがOFFなら登録せず、NAME/PATH・staticLiteral由来の接続可否を変更しません。
|
|
80
|
+
|
|
81
|
+
登録はoptional API(apiVersion:1)に限定し、RUNTIME_DISPOSED/明示disposeで解除します。起動フラグOFF+再読込で従来経路へ切り戻せます。依存を戻す場合はmanifest/lock/実解決を一組で復旧します。npm公開や後続段階の動的候補は含みません。
|
|
82
|
+
|
|
83
|
+
Schemaが記述する契約の根拠は実getInfoの宣言と既存の純粋なruntime変換です。SchemaBundleのretrievalUriはこのローカル文書の識別子であり、URL配信済み・HTTP取得によるref解決を意味しません。Schemaは同梱文書だけでcompileします。
|
|
84
|
+
既存MAXの非空finiteなNumber alias(例`001`・`+1`・`0x10`)はNumberによる表示投影だけを行い、無変更rawを保存し直しません。空白・非finite・投影不能値はreadonlyとし、0/defaultを補いません。新しい入力にはこれらaliasを許可せずNP-finite-new-input-v1を適用します。
|
|
85
|
+
|
|
86
|
+
登録は拡張インスタンスの構築時に存在する任意の editor API を使用します。後からの API 追加や差し替えには自動追従しません。起動設定を変更した場合は GUI を再読み込みし、拡張インスタンスを再構築してください。
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ JSON and YAML input is limited to 256 KiB, nesting depth 64, and 50,000 values.
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
pnpm add --save-exact @kubohiroya/turbowarp-structured-data@0.6.
|
|
26
|
+
pnpm add --save-exact @kubohiroya/turbowarp-structured-data@0.6.1
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## Quick start
|
|
@@ -243,3 +243,16 @@ pnpm run check
|
|
|
243
243
|
SPDX-License-Identifier: MPL-2.0
|
|
244
244
|
|
|
245
245
|
Bundled third-party license terms are listed in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
246
|
+
|
|
247
|
+
## 固定引数の編集フォーム(S3-4)
|
|
248
|
+
|
|
249
|
+
共通エディターの起動時フラグ `blockEditorFixedInputs` とDialogsがONのGUIでは、`forEachAtPath` の `MAX` だけを固定フォームとして登録します。旧GUI・フラグOFFでは追加登録を行いません。Schemaの正本は `schemas/block-editor-fixed-inputs.schema.json#/$defs/forEachAtPath/properties/MAX`、codecと登録は `src/fixed-input-editors.ts` です。既存raw値・未変更alias・未知enumは無操作保存で書き換えず、reporterを評価しません。明示変更だけを検査し、他の引数やブロック宣言、保存形式を変更しません。
|
|
250
|
+
|
|
251
|
+
MAXは整数1〜1000です。新しい入力には共通の有限数値token規則も適用し、途中入力を保存しません。MVP flagがOFFなら登録せず、NAME/PATH・staticLiteral由来の接続可否を変更しません。
|
|
252
|
+
|
|
253
|
+
登録はoptional API(apiVersion:1)に限定し、RUNTIME_DISPOSED/明示disposeで解除します。起動フラグOFF+再読込で従来経路へ切り戻せます。依存を戻す場合はmanifest/lock/実解決を一組で復旧します。npm公開や後続段階の動的候補は含みません。
|
|
254
|
+
|
|
255
|
+
Schemaが記述する契約の根拠は実getInfoの宣言と既存の純粋なruntime変換です。SchemaBundleのretrievalUriはこのローカル文書の識別子であり、URL配信済み・HTTP取得によるref解決を意味しません。Schemaは同梱文書だけでcompileします。
|
|
256
|
+
既存MAXの非空finiteなNumber alias(例`001`・`+1`・`0x10`)はNumberによる表示投影だけを行い、無変更rawを保存し直しません。空白・非finite・投影不能値はreadonlyとし、0/defaultを補いません。新しい入力にはこれらaliasを許可せずNP-finite-new-input-v1を適用します。
|
|
257
|
+
|
|
258
|
+
Registration uses the optional editor API available when the extension instance is constructed. Adding or replacing that API later is not followed automatically; reload the GUI and reconstruct the extension instance after changing the startup configuration.
|
package/dist/structured-data.js
CHANGED
|
@@ -65,6 +65,66 @@
|
|
|
65
65
|
docsURI: "https://kubohiroya.github.io/turbowarp-structured-data/",
|
|
66
66
|
blockIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PHJlY3QgeD0iNCIgeT0iOCIgd2lkdGg9IjE4IiBoZWlnaHQ9IjE0IiByeD0iMyIgZmlsbD0iIzRDOTdGRiIvPjxyZWN0IHg9IjI2IiB5PSI4IiB3aWR0aD0iMTgiIGhlaWdodD0iMTQiIHJ4PSIzIiBmaWxsPSIjNTlDMDU5Ii8+PHJlY3QgeD0iMTUiIHk9IjI2IiB3aWR0aD0iMTgiIGhlaWdodD0iMTQiIHJ4PSIzIiBmaWxsPSIjRkZBQjE5Ii8+PC9zdmc+"
|
|
67
67
|
};
|
|
68
|
+
var JsonSnapshotError = class extends Error {
|
|
69
|
+
constructor(kind, dataPath) {
|
|
70
|
+
super("JSON snapshot failed.");
|
|
71
|
+
this.kind = kind;
|
|
72
|
+
this.dataPath = dataPath;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
function appendPointer(path, key) {
|
|
76
|
+
return `${path}/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`;
|
|
77
|
+
}
|
|
78
|
+
/** Copy JSON values without invoking accessors, toJSON, or input iterators. */
|
|
79
|
+
function snapshotJson(value) {
|
|
80
|
+
const active = /* @__PURE__ */ new WeakSet();
|
|
81
|
+
let remaining = 1e5;
|
|
82
|
+
const visit = (input, path, depth) => {
|
|
83
|
+
if (--remaining < 0 || depth > 128) throw new JsonSnapshotError("limit", path);
|
|
84
|
+
if (input === null || typeof input === "string" || typeof input === "boolean") return input;
|
|
85
|
+
if (typeof input === "number" && Number.isFinite(input)) return input;
|
|
86
|
+
if (typeof input !== "object" || input === null || active.has(input)) throw new JsonSnapshotError("invalid", path);
|
|
87
|
+
const array = Array.isArray(input);
|
|
88
|
+
const prototype = Object.getPrototypeOf(input);
|
|
89
|
+
if (!array && prototype !== null && prototype !== Object.prototype) throw new JsonSnapshotError("invalid", path);
|
|
90
|
+
if (Object.getOwnPropertySymbols(input).length) throw new JsonSnapshotError("invalid", path);
|
|
91
|
+
active.add(input);
|
|
92
|
+
try {
|
|
93
|
+
if (array) {
|
|
94
|
+
const length = input.length;
|
|
95
|
+
if (!Number.isSafeInteger(length) || length > remaining) throw new JsonSnapshotError("limit", path);
|
|
96
|
+
const result = [];
|
|
97
|
+
for (let i = 0; i < length; i++) {
|
|
98
|
+
const child = appendPointer(path, String(i));
|
|
99
|
+
const descriptor = Object.getOwnPropertyDescriptor(input, i);
|
|
100
|
+
if (!descriptor || !("value" in descriptor)) throw new JsonSnapshotError("invalid", child);
|
|
101
|
+
result.push(visit(descriptor.value, child, depth + 1));
|
|
102
|
+
}
|
|
103
|
+
for (const key of Object.keys(input)) if (!/^(0|[1-9][0-9]*)$/.test(key) || Number(key) >= length) throw new JsonSnapshotError("invalid", appendPointer(path, key));
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
const result = {};
|
|
107
|
+
for (const key of Object.keys(input)) {
|
|
108
|
+
const child = appendPointer(path, key);
|
|
109
|
+
const descriptor = Object.getOwnPropertyDescriptor(input, key);
|
|
110
|
+
if (!descriptor || !("value" in descriptor)) throw new JsonSnapshotError("invalid", child);
|
|
111
|
+
Object.defineProperty(result, key, {
|
|
112
|
+
value: visit(descriptor.value, child, depth + 1),
|
|
113
|
+
enumerable: true,
|
|
114
|
+
writable: true,
|
|
115
|
+
configurable: true
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
} finally {
|
|
120
|
+
active.delete(input);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
return visit(value, "", 0);
|
|
124
|
+
}
|
|
125
|
+
function isJsonRecord(value) {
|
|
126
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
127
|
+
}
|
|
68
128
|
var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
69
129
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
70
130
|
exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = void 0;
|
|
@@ -2727,16 +2787,16 @@
|
|
|
2727
2787
|
}
|
|
2728
2788
|
}));
|
|
2729
2789
|
var data_exports = /* @__PURE__ */ __exportAll({
|
|
2730
|
-
$id: () => $id$
|
|
2790
|
+
$id: () => $id$10,
|
|
2731
2791
|
additionalProperties: () => false,
|
|
2732
2792
|
default: () => data_default,
|
|
2733
2793
|
description: () => description,
|
|
2734
2794
|
properties: () => properties$9,
|
|
2735
2795
|
required: () => required,
|
|
2736
2796
|
type: () => type$9
|
|
2737
|
-
}), $id$
|
|
2797
|
+
}), $id$10, description, type$9, required, properties$9, data_default;
|
|
2738
2798
|
var init_data = __esmMin((() => {
|
|
2739
|
-
$id$
|
|
2799
|
+
$id$10 = "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#";
|
|
2740
2800
|
description = "Meta-schema for $data reference (JSON AnySchema extension proposal)";
|
|
2741
2801
|
type$9 = "object";
|
|
2742
2802
|
required = ["$data"];
|
|
@@ -2745,7 +2805,7 @@
|
|
|
2745
2805
|
"anyOf": [{ "format": "relative-json-pointer" }, { "format": "json-pointer" }]
|
|
2746
2806
|
} };
|
|
2747
2807
|
data_default = {
|
|
2748
|
-
$id: $id$
|
|
2808
|
+
$id: $id$10,
|
|
2749
2809
|
description,
|
|
2750
2810
|
type: type$9,
|
|
2751
2811
|
required,
|
|
@@ -5997,18 +6057,18 @@
|
|
|
5997
6057
|
};
|
|
5998
6058
|
}));
|
|
5999
6059
|
var json_schema_draft_07_exports = /* @__PURE__ */ __exportAll({
|
|
6000
|
-
$id: () => $id$
|
|
6001
|
-
$schema: () => $schema$
|
|
6060
|
+
$id: () => $id$9,
|
|
6061
|
+
$schema: () => $schema$9,
|
|
6002
6062
|
default: () => json_schema_draft_07_default,
|
|
6003
6063
|
definitions: () => definitions$1,
|
|
6004
6064
|
properties: () => properties$8,
|
|
6005
6065
|
title: () => title$8,
|
|
6006
6066
|
type: () => type$8
|
|
6007
6067
|
});
|
|
6008
|
-
var $schema$
|
|
6068
|
+
var $schema$9, $id$9, title$8, definitions$1, type$8, properties$8, json_schema_draft_07_default;
|
|
6009
6069
|
var init_json_schema_draft_07 = __esmMin((() => {
|
|
6010
|
-
$schema$
|
|
6011
|
-
$id$
|
|
6070
|
+
$schema$9 = "http://json-schema.org/draft-07/schema#";
|
|
6071
|
+
$id$9 = "http://json-schema.org/draft-07/schema#";
|
|
6012
6072
|
title$8 = "Core schema meta-schema";
|
|
6013
6073
|
definitions$1 = {
|
|
6014
6074
|
"schemaArray": {
|
|
@@ -6139,8 +6199,8 @@
|
|
|
6139
6199
|
"not": { "$ref": "#" }
|
|
6140
6200
|
};
|
|
6141
6201
|
json_schema_draft_07_default = {
|
|
6142
|
-
$schema: $schema$
|
|
6143
|
-
$id: $id$
|
|
6202
|
+
$schema: $schema$9,
|
|
6203
|
+
$id: $id$9,
|
|
6144
6204
|
title: title$8,
|
|
6145
6205
|
definitions: definitions$1,
|
|
6146
6206
|
type: type$8,
|
|
@@ -6512,8 +6572,8 @@
|
|
|
6512
6572
|
var schema_exports = /* @__PURE__ */ __exportAll({
|
|
6513
6573
|
$comment: () => $comment,
|
|
6514
6574
|
$dynamicAnchor: () => $dynamicAnchor$7,
|
|
6515
|
-
$id: () => $id$
|
|
6516
|
-
$schema: () => $schema$
|
|
6575
|
+
$id: () => $id$8,
|
|
6576
|
+
$schema: () => $schema$8,
|
|
6517
6577
|
$vocabulary: () => $vocabulary$7,
|
|
6518
6578
|
allOf: () => allOf,
|
|
6519
6579
|
default: () => schema_default,
|
|
@@ -6521,10 +6581,10 @@
|
|
|
6521
6581
|
title: () => title$7,
|
|
6522
6582
|
type: () => type$7
|
|
6523
6583
|
});
|
|
6524
|
-
var $schema$
|
|
6584
|
+
var $schema$8, $id$8, $vocabulary$7, $dynamicAnchor$7, title$7, allOf, type$7, $comment, properties$7, schema_default;
|
|
6525
6585
|
var init_schema = __esmMin((() => {
|
|
6526
|
-
$schema$
|
|
6527
|
-
$id$
|
|
6586
|
+
$schema$8 = "https://json-schema.org/draft/2020-12/schema";
|
|
6587
|
+
$id$8 = "https://json-schema.org/draft/2020-12/schema";
|
|
6528
6588
|
$vocabulary$7 = {
|
|
6529
6589
|
"https://json-schema.org/draft/2020-12/vocab/core": true,
|
|
6530
6590
|
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
|
|
@@ -6574,8 +6634,8 @@
|
|
|
6574
6634
|
}
|
|
6575
6635
|
};
|
|
6576
6636
|
schema_default = {
|
|
6577
|
-
$schema: $schema$
|
|
6578
|
-
$id: $id$
|
|
6637
|
+
$schema: $schema$8,
|
|
6638
|
+
$id: $id$8,
|
|
6579
6639
|
$vocabulary: $vocabulary$7,
|
|
6580
6640
|
$dynamicAnchor: $dynamicAnchor$7,
|
|
6581
6641
|
title: title$7,
|
|
@@ -6586,20 +6646,20 @@
|
|
|
6586
6646
|
};
|
|
6587
6647
|
}));
|
|
6588
6648
|
var applicator_exports = /* @__PURE__ */ __exportAll({
|
|
6589
|
-
$defs: () => $defs$
|
|
6649
|
+
$defs: () => $defs$3,
|
|
6590
6650
|
$dynamicAnchor: () => $dynamicAnchor$6,
|
|
6591
|
-
$id: () => $id$
|
|
6592
|
-
$schema: () => $schema$
|
|
6651
|
+
$id: () => $id$7,
|
|
6652
|
+
$schema: () => $schema$7,
|
|
6593
6653
|
$vocabulary: () => $vocabulary$6,
|
|
6594
6654
|
default: () => applicator_default,
|
|
6595
6655
|
properties: () => properties$6,
|
|
6596
6656
|
title: () => title$6,
|
|
6597
6657
|
type: () => type$6
|
|
6598
6658
|
});
|
|
6599
|
-
var $schema$
|
|
6659
|
+
var $schema$7, $id$7, $vocabulary$6, $dynamicAnchor$6, title$6, type$6, properties$6, $defs$3, applicator_default;
|
|
6600
6660
|
var init_applicator = __esmMin((() => {
|
|
6601
|
-
$schema$
|
|
6602
|
-
$id$
|
|
6661
|
+
$schema$7 = "https://json-schema.org/draft/2020-12/schema";
|
|
6662
|
+
$id$7 = "https://json-schema.org/draft/2020-12/meta/applicator";
|
|
6603
6663
|
$vocabulary$6 = { "https://json-schema.org/draft/2020-12/vocab/applicator": true };
|
|
6604
6664
|
$dynamicAnchor$6 = "meta";
|
|
6605
6665
|
title$6 = "Applicator vocabulary meta-schema";
|
|
@@ -6634,36 +6694,36 @@
|
|
|
6634
6694
|
"oneOf": { "$ref": "#/$defs/schemaArray" },
|
|
6635
6695
|
"not": { "$dynamicRef": "#meta" }
|
|
6636
6696
|
};
|
|
6637
|
-
$defs$
|
|
6697
|
+
$defs$3 = { "schemaArray": {
|
|
6638
6698
|
"type": "array",
|
|
6639
6699
|
"minItems": 1,
|
|
6640
6700
|
"items": { "$dynamicRef": "#meta" }
|
|
6641
6701
|
} };
|
|
6642
6702
|
applicator_default = {
|
|
6643
|
-
$schema: $schema$
|
|
6644
|
-
$id: $id$
|
|
6703
|
+
$schema: $schema$7,
|
|
6704
|
+
$id: $id$7,
|
|
6645
6705
|
$vocabulary: $vocabulary$6,
|
|
6646
6706
|
$dynamicAnchor: $dynamicAnchor$6,
|
|
6647
6707
|
title: title$6,
|
|
6648
6708
|
type: type$6,
|
|
6649
6709
|
properties: properties$6,
|
|
6650
|
-
$defs: $defs$
|
|
6710
|
+
$defs: $defs$3
|
|
6651
6711
|
};
|
|
6652
6712
|
}));
|
|
6653
6713
|
var unevaluated_exports = /* @__PURE__ */ __exportAll({
|
|
6654
6714
|
$dynamicAnchor: () => $dynamicAnchor$5,
|
|
6655
|
-
$id: () => $id$
|
|
6656
|
-
$schema: () => $schema$
|
|
6715
|
+
$id: () => $id$6,
|
|
6716
|
+
$schema: () => $schema$6,
|
|
6657
6717
|
$vocabulary: () => $vocabulary$5,
|
|
6658
6718
|
default: () => unevaluated_default,
|
|
6659
6719
|
properties: () => properties$5,
|
|
6660
6720
|
title: () => title$5,
|
|
6661
6721
|
type: () => type$5
|
|
6662
6722
|
});
|
|
6663
|
-
var $schema$
|
|
6723
|
+
var $schema$6, $id$6, $vocabulary$5, $dynamicAnchor$5, title$5, type$5, properties$5, unevaluated_default;
|
|
6664
6724
|
var init_unevaluated = __esmMin((() => {
|
|
6665
|
-
$schema$
|
|
6666
|
-
$id$
|
|
6725
|
+
$schema$6 = "https://json-schema.org/draft/2020-12/schema";
|
|
6726
|
+
$id$6 = "https://json-schema.org/draft/2020-12/meta/unevaluated";
|
|
6667
6727
|
$vocabulary$5 = { "https://json-schema.org/draft/2020-12/vocab/unevaluated": true };
|
|
6668
6728
|
$dynamicAnchor$5 = "meta";
|
|
6669
6729
|
title$5 = "Unevaluated applicator vocabulary meta-schema";
|
|
@@ -6673,8 +6733,8 @@
|
|
|
6673
6733
|
"unevaluatedProperties": { "$dynamicRef": "#meta" }
|
|
6674
6734
|
};
|
|
6675
6735
|
unevaluated_default = {
|
|
6676
|
-
$schema: $schema$
|
|
6677
|
-
$id: $id$
|
|
6736
|
+
$schema: $schema$6,
|
|
6737
|
+
$id: $id$6,
|
|
6678
6738
|
$vocabulary: $vocabulary$5,
|
|
6679
6739
|
$dynamicAnchor: $dynamicAnchor$5,
|
|
6680
6740
|
title: title$5,
|
|
@@ -6684,18 +6744,18 @@
|
|
|
6684
6744
|
}));
|
|
6685
6745
|
var content_exports = /* @__PURE__ */ __exportAll({
|
|
6686
6746
|
$dynamicAnchor: () => $dynamicAnchor$4,
|
|
6687
|
-
$id: () => $id$
|
|
6688
|
-
$schema: () => $schema$
|
|
6747
|
+
$id: () => $id$5,
|
|
6748
|
+
$schema: () => $schema$5,
|
|
6689
6749
|
$vocabulary: () => $vocabulary$4,
|
|
6690
6750
|
default: () => content_default,
|
|
6691
6751
|
properties: () => properties$4,
|
|
6692
6752
|
title: () => title$4,
|
|
6693
6753
|
type: () => type$4
|
|
6694
6754
|
});
|
|
6695
|
-
var $schema$
|
|
6755
|
+
var $schema$5, $id$5, $vocabulary$4, $dynamicAnchor$4, title$4, type$4, properties$4, content_default;
|
|
6696
6756
|
var init_content = __esmMin((() => {
|
|
6697
|
-
$schema$
|
|
6698
|
-
$id$
|
|
6757
|
+
$schema$5 = "https://json-schema.org/draft/2020-12/schema";
|
|
6758
|
+
$id$5 = "https://json-schema.org/draft/2020-12/meta/content";
|
|
6699
6759
|
$vocabulary$4 = { "https://json-schema.org/draft/2020-12/vocab/content": true };
|
|
6700
6760
|
$dynamicAnchor$4 = "meta";
|
|
6701
6761
|
title$4 = "Content vocabulary meta-schema";
|
|
@@ -6706,8 +6766,8 @@
|
|
|
6706
6766
|
"contentSchema": { "$dynamicRef": "#meta" }
|
|
6707
6767
|
};
|
|
6708
6768
|
content_default = {
|
|
6709
|
-
$schema: $schema$
|
|
6710
|
-
$id: $id$
|
|
6769
|
+
$schema: $schema$5,
|
|
6770
|
+
$id: $id$5,
|
|
6711
6771
|
$vocabulary: $vocabulary$4,
|
|
6712
6772
|
$dynamicAnchor: $dynamicAnchor$4,
|
|
6713
6773
|
title: title$4,
|
|
@@ -6716,20 +6776,20 @@
|
|
|
6716
6776
|
};
|
|
6717
6777
|
}));
|
|
6718
6778
|
var core_exports = /* @__PURE__ */ __exportAll({
|
|
6719
|
-
$defs: () => $defs$
|
|
6779
|
+
$defs: () => $defs$2,
|
|
6720
6780
|
$dynamicAnchor: () => $dynamicAnchor$3,
|
|
6721
|
-
$id: () => $id$
|
|
6722
|
-
$schema: () => $schema$
|
|
6781
|
+
$id: () => $id$4,
|
|
6782
|
+
$schema: () => $schema$4,
|
|
6723
6783
|
$vocabulary: () => $vocabulary$3,
|
|
6724
6784
|
default: () => core_default,
|
|
6725
6785
|
properties: () => properties$3,
|
|
6726
6786
|
title: () => title$3,
|
|
6727
6787
|
type: () => type$3
|
|
6728
6788
|
});
|
|
6729
|
-
var $schema$
|
|
6789
|
+
var $schema$4, $id$4, $vocabulary$3, $dynamicAnchor$3, title$3, type$3, properties$3, $defs$2, core_default;
|
|
6730
6790
|
var init_core = __esmMin((() => {
|
|
6731
|
-
$schema$
|
|
6732
|
-
$id$
|
|
6791
|
+
$schema$4 = "https://json-schema.org/draft/2020-12/schema";
|
|
6792
|
+
$id$4 = "https://json-schema.org/draft/2020-12/meta/core";
|
|
6733
6793
|
$vocabulary$3 = { "https://json-schema.org/draft/2020-12/vocab/core": true };
|
|
6734
6794
|
$dynamicAnchor$3 = "meta";
|
|
6735
6795
|
title$3 = "Core vocabulary meta-schema";
|
|
@@ -6756,7 +6816,7 @@
|
|
|
6756
6816
|
"additionalProperties": { "$dynamicRef": "#meta" }
|
|
6757
6817
|
}
|
|
6758
6818
|
};
|
|
6759
|
-
$defs$
|
|
6819
|
+
$defs$2 = {
|
|
6760
6820
|
"anchorString": {
|
|
6761
6821
|
"type": "string",
|
|
6762
6822
|
"pattern": "^[A-Za-z_][-A-Za-z0-9._]*$"
|
|
@@ -6771,38 +6831,38 @@
|
|
|
6771
6831
|
}
|
|
6772
6832
|
};
|
|
6773
6833
|
core_default = {
|
|
6774
|
-
$schema: $schema$
|
|
6775
|
-
$id: $id$
|
|
6834
|
+
$schema: $schema$4,
|
|
6835
|
+
$id: $id$4,
|
|
6776
6836
|
$vocabulary: $vocabulary$3,
|
|
6777
6837
|
$dynamicAnchor: $dynamicAnchor$3,
|
|
6778
6838
|
title: title$3,
|
|
6779
6839
|
type: type$3,
|
|
6780
6840
|
properties: properties$3,
|
|
6781
|
-
$defs: $defs$
|
|
6841
|
+
$defs: $defs$2
|
|
6782
6842
|
};
|
|
6783
6843
|
}));
|
|
6784
6844
|
var format_annotation_exports = /* @__PURE__ */ __exportAll({
|
|
6785
6845
|
$dynamicAnchor: () => $dynamicAnchor$2,
|
|
6786
|
-
$id: () => $id$
|
|
6787
|
-
$schema: () => $schema$
|
|
6846
|
+
$id: () => $id$3,
|
|
6847
|
+
$schema: () => $schema$3,
|
|
6788
6848
|
$vocabulary: () => $vocabulary$2,
|
|
6789
6849
|
default: () => format_annotation_default,
|
|
6790
6850
|
properties: () => properties$2,
|
|
6791
6851
|
title: () => title$2,
|
|
6792
6852
|
type: () => type$2
|
|
6793
6853
|
});
|
|
6794
|
-
var $schema$
|
|
6854
|
+
var $schema$3, $id$3, $vocabulary$2, $dynamicAnchor$2, title$2, type$2, properties$2, format_annotation_default;
|
|
6795
6855
|
var init_format_annotation = __esmMin((() => {
|
|
6796
|
-
$schema$
|
|
6797
|
-
$id$
|
|
6856
|
+
$schema$3 = "https://json-schema.org/draft/2020-12/schema";
|
|
6857
|
+
$id$3 = "https://json-schema.org/draft/2020-12/meta/format-annotation";
|
|
6798
6858
|
$vocabulary$2 = { "https://json-schema.org/draft/2020-12/vocab/format-annotation": true };
|
|
6799
6859
|
$dynamicAnchor$2 = "meta";
|
|
6800
6860
|
title$2 = "Format vocabulary meta-schema for annotation results";
|
|
6801
6861
|
type$2 = ["object", "boolean"];
|
|
6802
6862
|
properties$2 = { "format": { "type": "string" } };
|
|
6803
6863
|
format_annotation_default = {
|
|
6804
|
-
$schema: $schema$
|
|
6805
|
-
$id: $id$
|
|
6864
|
+
$schema: $schema$3,
|
|
6865
|
+
$id: $id$3,
|
|
6806
6866
|
$vocabulary: $vocabulary$2,
|
|
6807
6867
|
$dynamicAnchor: $dynamicAnchor$2,
|
|
6808
6868
|
title: title$2,
|
|
@@ -6812,18 +6872,18 @@
|
|
|
6812
6872
|
}));
|
|
6813
6873
|
var meta_data_exports = /* @__PURE__ */ __exportAll({
|
|
6814
6874
|
$dynamicAnchor: () => $dynamicAnchor$1,
|
|
6815
|
-
$id: () => $id$
|
|
6816
|
-
$schema: () => $schema$
|
|
6875
|
+
$id: () => $id$2,
|
|
6876
|
+
$schema: () => $schema$2,
|
|
6817
6877
|
$vocabulary: () => $vocabulary$1,
|
|
6818
6878
|
default: () => meta_data_default,
|
|
6819
6879
|
properties: () => properties$1,
|
|
6820
6880
|
title: () => title$1,
|
|
6821
6881
|
type: () => type$1
|
|
6822
6882
|
});
|
|
6823
|
-
var $schema$
|
|
6883
|
+
var $schema$2, $id$2, $vocabulary$1, $dynamicAnchor$1, title$1, type$1, properties$1, meta_data_default;
|
|
6824
6884
|
var init_meta_data = __esmMin((() => {
|
|
6825
|
-
$schema$
|
|
6826
|
-
$id$
|
|
6885
|
+
$schema$2 = "https://json-schema.org/draft/2020-12/schema";
|
|
6886
|
+
$id$2 = "https://json-schema.org/draft/2020-12/meta/meta-data";
|
|
6827
6887
|
$vocabulary$1 = { "https://json-schema.org/draft/2020-12/vocab/meta-data": true };
|
|
6828
6888
|
$dynamicAnchor$1 = "meta";
|
|
6829
6889
|
title$1 = "Meta-data vocabulary meta-schema";
|
|
@@ -6850,8 +6910,8 @@
|
|
|
6850
6910
|
}
|
|
6851
6911
|
};
|
|
6852
6912
|
meta_data_default = {
|
|
6853
|
-
$schema: $schema$
|
|
6854
|
-
$id: $id$
|
|
6913
|
+
$schema: $schema$2,
|
|
6914
|
+
$id: $id$2,
|
|
6855
6915
|
$vocabulary: $vocabulary$1,
|
|
6856
6916
|
$dynamicAnchor: $dynamicAnchor$1,
|
|
6857
6917
|
title: title$1,
|
|
@@ -6860,20 +6920,20 @@
|
|
|
6860
6920
|
};
|
|
6861
6921
|
}));
|
|
6862
6922
|
var validation_exports = /* @__PURE__ */ __exportAll({
|
|
6863
|
-
$defs: () => $defs,
|
|
6923
|
+
$defs: () => $defs$1,
|
|
6864
6924
|
$dynamicAnchor: () => $dynamicAnchor,
|
|
6865
|
-
$id: () => $id,
|
|
6866
|
-
$schema: () => $schema,
|
|
6925
|
+
$id: () => $id$1,
|
|
6926
|
+
$schema: () => $schema$1,
|
|
6867
6927
|
$vocabulary: () => $vocabulary,
|
|
6868
6928
|
default: () => validation_default,
|
|
6869
6929
|
properties: () => properties,
|
|
6870
6930
|
title: () => title,
|
|
6871
6931
|
type: () => type
|
|
6872
6932
|
});
|
|
6873
|
-
var $schema, $id, $vocabulary, $dynamicAnchor, title, type, properties, $defs, validation_default;
|
|
6933
|
+
var $schema$1, $id$1, $vocabulary, $dynamicAnchor, title, type, properties, $defs$1, validation_default;
|
|
6874
6934
|
var init_validation = __esmMin((() => {
|
|
6875
|
-
$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
6876
|
-
$id = "https://json-schema.org/draft/2020-12/meta/validation";
|
|
6935
|
+
$schema$1 = "https://json-schema.org/draft/2020-12/schema";
|
|
6936
|
+
$id$1 = "https://json-schema.org/draft/2020-12/meta/validation";
|
|
6877
6937
|
$vocabulary = { "https://json-schema.org/draft/2020-12/vocab/validation": true };
|
|
6878
6938
|
$dynamicAnchor = "meta";
|
|
6879
6939
|
title = "Validation vocabulary meta-schema";
|
|
@@ -6923,7 +6983,7 @@
|
|
|
6923
6983
|
"additionalProperties": { "$ref": "#/$defs/stringArray" }
|
|
6924
6984
|
}
|
|
6925
6985
|
};
|
|
6926
|
-
$defs = {
|
|
6986
|
+
$defs$1 = {
|
|
6927
6987
|
"nonNegativeInteger": {
|
|
6928
6988
|
"type": "integer",
|
|
6929
6989
|
"minimum": 0
|
|
@@ -6949,14 +7009,14 @@
|
|
|
6949
7009
|
}
|
|
6950
7010
|
};
|
|
6951
7011
|
validation_default = {
|
|
6952
|
-
$schema,
|
|
6953
|
-
$id,
|
|
7012
|
+
$schema: $schema$1,
|
|
7013
|
+
$id: $id$1,
|
|
6954
7014
|
$vocabulary,
|
|
6955
7015
|
$dynamicAnchor,
|
|
6956
7016
|
title,
|
|
6957
7017
|
type,
|
|
6958
7018
|
properties,
|
|
6959
|
-
$defs
|
|
7019
|
+
$defs: $defs$1
|
|
6960
7020
|
};
|
|
6961
7021
|
}));
|
|
6962
7022
|
var require_json_schema_2020_12 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
@@ -7349,66 +7409,6 @@
|
|
|
7349
7409
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7350
7410
|
exports.default = formatsPlugin;
|
|
7351
7411
|
}));
|
|
7352
|
-
var JsonSnapshotError = class extends Error {
|
|
7353
|
-
constructor(kind, dataPath) {
|
|
7354
|
-
super("JSON snapshot failed.");
|
|
7355
|
-
this.kind = kind;
|
|
7356
|
-
this.dataPath = dataPath;
|
|
7357
|
-
}
|
|
7358
|
-
};
|
|
7359
|
-
function appendPointer(path, key) {
|
|
7360
|
-
return `${path}/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`;
|
|
7361
|
-
}
|
|
7362
|
-
/** Copy JSON values without invoking accessors, toJSON, or input iterators. */
|
|
7363
|
-
function snapshotJson(value) {
|
|
7364
|
-
const active = /* @__PURE__ */ new WeakSet();
|
|
7365
|
-
let remaining = 1e5;
|
|
7366
|
-
const visit = (input, path, depth) => {
|
|
7367
|
-
if (--remaining < 0 || depth > 128) throw new JsonSnapshotError("limit", path);
|
|
7368
|
-
if (input === null || typeof input === "string" || typeof input === "boolean") return input;
|
|
7369
|
-
if (typeof input === "number" && Number.isFinite(input)) return input;
|
|
7370
|
-
if (typeof input !== "object" || input === null || active.has(input)) throw new JsonSnapshotError("invalid", path);
|
|
7371
|
-
const array = Array.isArray(input);
|
|
7372
|
-
const prototype = Object.getPrototypeOf(input);
|
|
7373
|
-
if (!array && prototype !== null && prototype !== Object.prototype) throw new JsonSnapshotError("invalid", path);
|
|
7374
|
-
if (Object.getOwnPropertySymbols(input).length) throw new JsonSnapshotError("invalid", path);
|
|
7375
|
-
active.add(input);
|
|
7376
|
-
try {
|
|
7377
|
-
if (array) {
|
|
7378
|
-
const length = input.length;
|
|
7379
|
-
if (!Number.isSafeInteger(length) || length > remaining) throw new JsonSnapshotError("limit", path);
|
|
7380
|
-
const result = [];
|
|
7381
|
-
for (let i = 0; i < length; i++) {
|
|
7382
|
-
const child = appendPointer(path, String(i));
|
|
7383
|
-
const descriptor = Object.getOwnPropertyDescriptor(input, i);
|
|
7384
|
-
if (!descriptor || !("value" in descriptor)) throw new JsonSnapshotError("invalid", child);
|
|
7385
|
-
result.push(visit(descriptor.value, child, depth + 1));
|
|
7386
|
-
}
|
|
7387
|
-
for (const key of Object.keys(input)) if (!/^(0|[1-9][0-9]*)$/.test(key) || Number(key) >= length) throw new JsonSnapshotError("invalid", appendPointer(path, key));
|
|
7388
|
-
return result;
|
|
7389
|
-
}
|
|
7390
|
-
const result = {};
|
|
7391
|
-
for (const key of Object.keys(input)) {
|
|
7392
|
-
const child = appendPointer(path, key);
|
|
7393
|
-
const descriptor = Object.getOwnPropertyDescriptor(input, key);
|
|
7394
|
-
if (!descriptor || !("value" in descriptor)) throw new JsonSnapshotError("invalid", child);
|
|
7395
|
-
Object.defineProperty(result, key, {
|
|
7396
|
-
value: visit(descriptor.value, child, depth + 1),
|
|
7397
|
-
enumerable: true,
|
|
7398
|
-
writable: true,
|
|
7399
|
-
configurable: true
|
|
7400
|
-
});
|
|
7401
|
-
}
|
|
7402
|
-
return result;
|
|
7403
|
-
} finally {
|
|
7404
|
-
active.delete(input);
|
|
7405
|
-
}
|
|
7406
|
-
};
|
|
7407
|
-
return visit(value, "", 0);
|
|
7408
|
-
}
|
|
7409
|
-
function isJsonRecord(value) {
|
|
7410
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7411
|
-
}
|
|
7412
7412
|
var import_ajv = require_ajv();
|
|
7413
7413
|
var import__2020 = require__2020();
|
|
7414
7414
|
var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
|
|
@@ -7753,6 +7753,156 @@
|
|
|
7753
7753
|
});
|
|
7754
7754
|
}
|
|
7755
7755
|
}
|
|
7756
|
+
var numberToken = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/u;
|
|
7757
|
+
var invalidNumber = Object.freeze({
|
|
7758
|
+
kind: "invalid",
|
|
7759
|
+
code: "fixed-number-input-invalid"
|
|
7760
|
+
});
|
|
7761
|
+
/**
|
|
7762
|
+
* Parse a NEW numeric draft according to NP-finite-new-input-v1.
|
|
7763
|
+
* Never apply this to opening/no-op raw values or use it as an owner validator.
|
|
7764
|
+
* Keep the validated token so negative zero, precision and exponent spelling survive.
|
|
7765
|
+
*/
|
|
7766
|
+
function parseFixedNumberInput(input) {
|
|
7767
|
+
if (typeof input === "number") {
|
|
7768
|
+
if (!Number.isFinite(input)) return invalidNumber;
|
|
7769
|
+
return Object.freeze({
|
|
7770
|
+
kind: "valid",
|
|
7771
|
+
token: Object.is(input, -0) ? "-0" : String(input),
|
|
7772
|
+
value: input
|
|
7773
|
+
});
|
|
7774
|
+
}
|
|
7775
|
+
if (typeof input !== "string") return invalidNumber;
|
|
7776
|
+
const token = input.trim();
|
|
7777
|
+
if (!numberToken.test(token)) return invalidNumber;
|
|
7778
|
+
const value = Number(token);
|
|
7779
|
+
return Number.isFinite(value) ? Object.freeze({
|
|
7780
|
+
kind: "valid",
|
|
7781
|
+
token,
|
|
7782
|
+
value
|
|
7783
|
+
}) : invalidNumber;
|
|
7784
|
+
}
|
|
7785
|
+
var block_editor_fixed_inputs_schema_default = {
|
|
7786
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7787
|
+
$id: "https://kubohiroya.github.io/turbowarp-structured-data/schemas/block-editor-fixed-inputs.schema.json",
|
|
7788
|
+
$defs: { "forEachAtPath": {
|
|
7789
|
+
"type": "object",
|
|
7790
|
+
"properties": { "MAX": {
|
|
7791
|
+
"type": "integer",
|
|
7792
|
+
"minimum": 1,
|
|
7793
|
+
"maximum": 1e3
|
|
7794
|
+
} },
|
|
7795
|
+
"required": ["MAX"],
|
|
7796
|
+
"additionalProperties": true
|
|
7797
|
+
} }
|
|
7798
|
+
};
|
|
7799
|
+
var source$1 = {
|
|
7800
|
+
repository: "turbowarp-structured-data",
|
|
7801
|
+
path: "schemas/block-editor-fixed-inputs.schema.json",
|
|
7802
|
+
symbol: "#/$defs/forEachAtPath/properties/MAX"
|
|
7803
|
+
};
|
|
7804
|
+
/** The on-disk owner Schema is canonical; this is its single-field projection. */
|
|
7805
|
+
var fixedInputSchemaBundle = {
|
|
7806
|
+
identity: {
|
|
7807
|
+
ownerId: "turbowarp-structured-data",
|
|
7808
|
+
contractId: "forEachAtPath.MAX",
|
|
7809
|
+
revision: "fixed-inputs-v1",
|
|
7810
|
+
variantId: "default"
|
|
7811
|
+
},
|
|
7812
|
+
dialect: "2020-12",
|
|
7813
|
+
root: {
|
|
7814
|
+
retrievalUri: "https://kubohiroya.github.io/turbowarp-structured-data/schemas/forEachAtPath-MAX.schema.json",
|
|
7815
|
+
document: block_editor_fixed_inputs_schema_default.$defs.forEachAtPath.properties.MAX,
|
|
7816
|
+
artifact: {
|
|
7817
|
+
role: "canonical-schema",
|
|
7818
|
+
source: source$1
|
|
7819
|
+
}
|
|
7820
|
+
},
|
|
7821
|
+
resources: [],
|
|
7822
|
+
provenance: {
|
|
7823
|
+
canonicalSources: [source$1, {
|
|
7824
|
+
repository: "turbowarp-structured-data",
|
|
7825
|
+
path: "src/core.ts",
|
|
7826
|
+
symbol: "iterationEntries"
|
|
7827
|
+
}],
|
|
7828
|
+
generatedFiles: [{
|
|
7829
|
+
repository: "turbowarp-structured-data",
|
|
7830
|
+
path: "docs/schemas/block-editor-fixed-inputs.schema.json"
|
|
7831
|
+
}],
|
|
7832
|
+
referenceSchemas: [],
|
|
7833
|
+
generationSources: [{
|
|
7834
|
+
repository: "turbowarp-structured-data",
|
|
7835
|
+
path: "scripts/generate-fixed-input-docs.mjs"
|
|
7836
|
+
}]
|
|
7837
|
+
}
|
|
7838
|
+
};
|
|
7839
|
+
var fixedInputEditorDefinitions = [{
|
|
7840
|
+
apiVersion: 1,
|
|
7841
|
+
extensionId: extensionConfig.id,
|
|
7842
|
+
editorId: "forEachAtPath-fixed-inputs",
|
|
7843
|
+
opcodes: [`${extensionConfig.id}_forEachAtPath`],
|
|
7844
|
+
contractId: "turbowarp-structured-data:forEachAtPath.MAX",
|
|
7845
|
+
contractRevision: "fixed-inputs-v1",
|
|
7846
|
+
bindings: [{
|
|
7847
|
+
argument: "MAX",
|
|
7848
|
+
schemaBundle: fixedInputSchemaBundle,
|
|
7849
|
+
control: {
|
|
7850
|
+
kind: "number",
|
|
7851
|
+
label: "MAX"
|
|
7852
|
+
},
|
|
7853
|
+
read(value) {
|
|
7854
|
+
if (typeof value !== "string" && typeof value !== "number") throw new TypeError("Expected a literal maximum.");
|
|
7855
|
+
if (typeof value === "string" && value.trim() === "") throw new TypeError("Blank maximum stays readonly.");
|
|
7856
|
+
const number = Number(value);
|
|
7857
|
+
if (!Number.isFinite(number)) throw new TypeError("Maximum must be finite.");
|
|
7858
|
+
return number;
|
|
7859
|
+
},
|
|
7860
|
+
encode(value) {
|
|
7861
|
+
const parsed = parseFixedNumberInput(value);
|
|
7862
|
+
if (parsed.kind !== "valid") throw new TypeError("Expected a finite numeric token.");
|
|
7863
|
+
return parsed.token;
|
|
7864
|
+
},
|
|
7865
|
+
validateCandidate(value) {
|
|
7866
|
+
const parsed = parseFixedNumberInput(value);
|
|
7867
|
+
return parsed.kind === "valid" && Number.isInteger(parsed.value) && parsed.value >= 1 && parsed.value <= 1e3 ? [] : [{
|
|
7868
|
+
path: "/inputs/MAX",
|
|
7869
|
+
message: "Maximum must be an integer from 1 to 1000."
|
|
7870
|
+
}];
|
|
7871
|
+
}
|
|
7872
|
+
}],
|
|
7873
|
+
validationContext: () => ({
|
|
7874
|
+
consumerId: extensionConfig.id,
|
|
7875
|
+
nowMs: Date.now(),
|
|
7876
|
+
settings: null
|
|
7877
|
+
})
|
|
7878
|
+
}];
|
|
7879
|
+
/** Register metadata only; the GUI startup capability owns editor activation. */
|
|
7880
|
+
function registerFixedInputEditors(scratch, definitions, runtimeOverride) {
|
|
7881
|
+
const host = scratch;
|
|
7882
|
+
const api = host.gui?.blockEditors;
|
|
7883
|
+
if (!definitions.length || api?.apiVersion !== 1 || typeof api.registerFixedInputEditor !== "function") return () => {};
|
|
7884
|
+
const runtime = runtimeOverride ?? host.vm?.runtime;
|
|
7885
|
+
const removers = [];
|
|
7886
|
+
let active = true;
|
|
7887
|
+
const dispose = () => {
|
|
7888
|
+
if (!active) return;
|
|
7889
|
+
active = false;
|
|
7890
|
+
runtime?.off?.("RUNTIME_DISPOSED", dispose);
|
|
7891
|
+
for (const remove of removers.splice(0).reverse()) remove();
|
|
7892
|
+
};
|
|
7893
|
+
try {
|
|
7894
|
+
for (const definition of definitions) {
|
|
7895
|
+
const remove = api.registerFixedInputEditor.call(api, definition);
|
|
7896
|
+
if (typeof remove !== "function") throw new TypeError("Invalid fixed input registration disposer.");
|
|
7897
|
+
removers.push(remove);
|
|
7898
|
+
}
|
|
7899
|
+
runtime?.on?.("RUNTIME_DISPOSED", dispose);
|
|
7900
|
+
} catch (error) {
|
|
7901
|
+
dispose();
|
|
7902
|
+
throw error;
|
|
7903
|
+
}
|
|
7904
|
+
return dispose;
|
|
7905
|
+
}
|
|
7756
7906
|
function deepFreeze(value) {
|
|
7757
7907
|
if (value !== null && typeof value === "object") {
|
|
7758
7908
|
Object.values(value).forEach(deepFreeze);
|
|
@@ -14361,6 +14511,8 @@
|
|
|
14361
14511
|
"markdown",
|
|
14362
14512
|
"raw"
|
|
14363
14513
|
];
|
|
14514
|
+
var NAMED_DATA_SCHEMA_ID_PATTERN = /^[a-z][a-z0-9.-]{0,127}$/u;
|
|
14515
|
+
var NAMED_DATA_SCHEMA_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/u;
|
|
14364
14516
|
var NAMED_DATA_ERROR_CODES = [
|
|
14365
14517
|
"NAMED_DATA_INVALID_REF",
|
|
14366
14518
|
"NAMED_DATA_INVALID_REGISTRY",
|
|
@@ -14369,6 +14521,9 @@
|
|
|
14369
14521
|
"NAMED_DATA_NOT_FOUND",
|
|
14370
14522
|
"NAMED_DATA_KIND_MISMATCH",
|
|
14371
14523
|
"NAMED_DATA_SCOPE_MISMATCH",
|
|
14524
|
+
"NAMED_DATA_SCHEMA_NOT_FOUND",
|
|
14525
|
+
"NAMED_DATA_SCHEMA_VERSION_MISMATCH",
|
|
14526
|
+
"NAMED_DATA_SCHEMA_UNRESOLVED",
|
|
14372
14527
|
"NAMED_DATA_REPRESENTATION_UNSUPPORTED",
|
|
14373
14528
|
"NAMED_DATA_INVALID_METADATA",
|
|
14374
14529
|
"NAMED_DATA_BODY_TOO_LARGE",
|
|
@@ -14589,9 +14744,21 @@
|
|
|
14589
14744
|
if (!reference || typeof reference !== "object") throw invalidReference();
|
|
14590
14745
|
requireNamespace(reference.namespace);
|
|
14591
14746
|
if (typeof reference.name !== "string" || reference.name.length === 0 || reference.name.length > 256 || containsControlCharacter(reference.name) || !NAMED_DATA_KINDS.includes(reference.kind) || !NAMED_DATA_SCOPES.includes(reference.scope) || !NAMED_DATA_REPRESENTATIONS.includes(representation)) throw invalidReference();
|
|
14747
|
+
if (reference.schemaRef !== void 0) validateSchemaRef(reference.kind, reference.schemaRef);
|
|
14592
14748
|
}
|
|
14593
14749
|
function validateMetadata(metadata, reference, representation) {
|
|
14594
14750
|
if (metadata.representation !== representation || !isNativeRepresentation(metadata.reference.kind, metadata.nativeRepresentation) || metadata.reference.namespace !== reference.namespace || metadata.reference.name !== reference.name || metadata.reference.kind !== reference.kind || metadata.reference.scope !== reference.scope || typeof metadata.mediaType !== "string" || metadata.mediaType.length === 0 || typeof metadata.revision !== "string" || metadata.revision.length === 0 || typeof metadata.replayable !== "boolean" || metadata.byteLength !== void 0 && (!Number.isSafeInteger(metadata.byteLength) || metadata.byteLength < 0) || metadata.digest !== void 0 && !/^sha256-[A-Za-z0-9_-]+$/u.test(metadata.digest)) throw new NamedDataError("NAMED_DATA_INVALID_METADATA", "Provider returned invalid metadata.");
|
|
14751
|
+
const expectedSchema = reference.schemaRef;
|
|
14752
|
+
const actualSchema = metadata.schemaRef;
|
|
14753
|
+
if (actualSchema !== void 0) validateSchemaRef(metadata.reference.kind, actualSchema, "NAMED_DATA_INVALID_METADATA");
|
|
14754
|
+
if (metadata.reference.schemaRef !== void 0) validateSchemaRef(metadata.reference.kind, metadata.reference.schemaRef, "NAMED_DATA_INVALID_METADATA");
|
|
14755
|
+
if (!sameSchemaRef(expectedSchema, actualSchema) || !sameSchemaRef(expectedSchema, metadata.reference.schemaRef)) throw new NamedDataError("NAMED_DATA_SCHEMA_VERSION_MISMATCH", "Provider schemaRef does not match the requested reference.");
|
|
14756
|
+
}
|
|
14757
|
+
function validateSchemaRef(kind, schemaRef, errorCode = "NAMED_DATA_INVALID_REF") {
|
|
14758
|
+
if (kind !== "structured" || typeof schemaRef !== "object" || schemaRef === null || !NAMED_DATA_SCHEMA_ID_PATTERN.test(String(schemaRef.id ?? "")) || !NAMED_DATA_SCHEMA_VERSION_PATTERN.test(String(schemaRef.version ?? "")) || Object.keys(schemaRef).some((key) => key !== "id" && key !== "version")) throw new NamedDataError(errorCode, "Invalid schemaRef; schema references require a structured value, stable id, and full SemVer version.");
|
|
14759
|
+
}
|
|
14760
|
+
function sameSchemaRef(left, right) {
|
|
14761
|
+
return left === void 0 ? right === void 0 : right !== void 0 && left.id === right.id && left.version === right.version;
|
|
14595
14762
|
}
|
|
14596
14763
|
function isNativeRepresentation(kind, representation) {
|
|
14597
14764
|
if (kind === "structured") return representation === "json" || representation === "yaml";
|
|
@@ -14628,7 +14795,10 @@
|
|
|
14628
14795
|
const value = globalThis.__TW_NAMED_DATA_FEATURE_FLAGS__?.[name];
|
|
14629
14796
|
return value === true || value === "true";
|
|
14630
14797
|
}
|
|
14631
|
-
Object.freeze({
|
|
14798
|
+
Object.freeze({
|
|
14799
|
+
NAMED_DATA_REGISTRY_MVP: configuredFlag("NAMED_DATA_REGISTRY_MVP"),
|
|
14800
|
+
NAMED_DATA_SCHEMA_REF: configuredFlag("NAMED_DATA_SCHEMA_REF")
|
|
14801
|
+
});
|
|
14632
14802
|
var STRUCTURED_DATA_NAMESPACE = "structured";
|
|
14633
14803
|
var STRUCTURED_BODY_MAX_BYTES = 262144;
|
|
14634
14804
|
var StructuredDataNamedDataProvider = class {
|
|
@@ -14714,24 +14884,44 @@
|
|
|
14714
14884
|
var blockDefinitions = block_definitions_default.blocks;
|
|
14715
14885
|
var StructuredDataExtension = class {
|
|
14716
14886
|
constructor(enabled = isStructuredDataMvpEnabled(), namedDataEnabled = isNamedDataRegistryMvpEnabled()) {
|
|
14887
|
+
this.disposed = false;
|
|
14717
14888
|
this.registries = /* @__PURE__ */ new WeakMap();
|
|
14718
14889
|
this.iterationStacks = /* @__PURE__ */ new WeakMap();
|
|
14719
14890
|
this.nextRevision = 1;
|
|
14720
14891
|
this.enabled = enabled;
|
|
14721
14892
|
this.unregisterSourceEditors = registerSourceEditors(Scratch, enabled ? sourceEditorDefinitions : []);
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14893
|
+
const runtime = Scratch.vm?.runtime;
|
|
14894
|
+
const onDispose = () => {
|
|
14895
|
+
this.dispose();
|
|
14896
|
+
};
|
|
14897
|
+
const onStop = () => this.clearRuntimeState();
|
|
14898
|
+
this.releaseRuntimeListeners = () => {
|
|
14899
|
+
runtime?.off?.("RUNTIME_DISPOSED", onDispose);
|
|
14900
|
+
runtime?.off?.("PROJECT_STOP_ALL", onStop);
|
|
14901
|
+
};
|
|
14902
|
+
let unregisterFixed = () => {};
|
|
14903
|
+
try {
|
|
14904
|
+
unregisterFixed = registerFixedInputEditors(Scratch, enabled ? fixedInputEditorDefinitions : []);
|
|
14905
|
+
this.unregisterFixedInputEditors = unregisterFixed;
|
|
14906
|
+
if (namedDataEnabled) {
|
|
14907
|
+
this.namedDataProvider = new StructuredDataNamedDataProvider({ get: (target, name) => this.registries.get(target)?.get(name) });
|
|
14908
|
+
const runtime = Scratch.vm?.runtime;
|
|
14909
|
+
if (runtime) {
|
|
14910
|
+
this.namedDataRegistry = installNamedDataRegistry(runtime);
|
|
14911
|
+
this.namedDataRegistration = this.namedDataRegistry.registerProvider(this.namedDataProvider, { lifetime: "persistent" });
|
|
14912
|
+
this.unbindNamedDataRegistryLifecycle = bindNamedDataRegistryLifecycle(runtime, this.namedDataRegistry);
|
|
14913
|
+
runtime.on?.("RUNTIME_DISPOSED", onDispose);
|
|
14914
|
+
}
|
|
14732
14915
|
}
|
|
14916
|
+
runtime?.on?.("PROJECT_STOP_ALL", onStop);
|
|
14917
|
+
} catch (error) {
|
|
14918
|
+
this.releaseRuntimeListeners();
|
|
14919
|
+
unregisterFixed();
|
|
14920
|
+
this.unregisterSourceEditors();
|
|
14921
|
+
this.unbindNamedDataRegistryLifecycle?.();
|
|
14922
|
+
this.namedDataRegistration?.unregister().catch(() => {});
|
|
14923
|
+
throw error;
|
|
14733
14924
|
}
|
|
14734
|
-
Scratch.vm?.runtime?.on?.("PROJECT_STOP_ALL", () => this.clearRuntimeState());
|
|
14735
14925
|
}
|
|
14736
14926
|
getNamedDataProvider() {
|
|
14737
14927
|
return this.namedDataProvider;
|
|
@@ -14740,6 +14930,10 @@
|
|
|
14740
14930
|
return this.namedDataRegistry;
|
|
14741
14931
|
}
|
|
14742
14932
|
async dispose() {
|
|
14933
|
+
if (this.disposed) return;
|
|
14934
|
+
this.disposed = true;
|
|
14935
|
+
this.releaseRuntimeListeners();
|
|
14936
|
+
this.unregisterFixedInputEditors();
|
|
14743
14937
|
this.unregisterSourceEditors();
|
|
14744
14938
|
await this.namedDataRegistration?.unregister();
|
|
14745
14939
|
this.unbindNamedDataRegistryLifecycle?.();
|
package/docs/index.html
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
<li><a href="#block-currentIndex"><code>current index</code></a></li>
|
|
53
53
|
<li><a href="#block-currentValueJson"><code>current value JSON</code></a></li>
|
|
54
54
|
</ul></nav>
|
|
55
|
-
<article id="block-parseJson" class="block-reference-entry"><h3><code>parse JSON [TEXT] as [NAME]</code></h3><p>Parse JSON text into the target-local structured data namespace.</p><p>Block type: COMMAND. Opcode: <code>parseJson</code>. <a href="#block-parseJson">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>TEXT</code></th><td>STRING</td><td><code>{"name":"TurboWarp"}</code></td><td></td></tr><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-parseYaml" class="block-reference-entry"><h3><code>parse YAML [TEXT] as [NAME]</code></h3><p>Parse safe YAML text into the target-local structured data namespace.</p><p>Block type: COMMAND. Opcode: <code>parseYaml</code>. <a href="#block-parseYaml">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>TEXT</code></th><td>STRING</td><td><code>name: TurboWarp</code></td><td></td></tr><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-toJson" class="block-reference-entry"><h3><code>to JSON [NAME]</code></h3><p>Render named structured data as canonical JSON.</p><p>Block type: REPORTER. Opcode: <code>toJson</code>. <a href="#block-toJson">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-toYaml" class="block-reference-entry"><h3><code>to YAML [NAME]</code></h3><p>Render named structured data as deterministic YAML.</p><p>Block type: REPORTER. Opcode: <code>toYaml</code>. <a href="#block-toYaml">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-hasStructuredData" class="block-reference-entry"><h3><code>structured data [NAME] exists?</code></h3><p>Report whether the current target has named structured data.</p><p>Block type: BOOLEAN. Opcode: <code>hasStructuredData</code>. <a href="#block-hasStructuredData">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-deleteStructuredData" class="block-reference-entry"><h3><code>delete structured data [NAME]</code></h3><p>Delete named structured data from the current target.</p><p>Block type: COMMAND. Opcode: <code>deleteStructuredData</code>. <a href="#block-deleteStructuredData">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-getJsonAtPath" class="block-reference-entry"><h3><code>get JSON from [NAME] at path [PATH]</code></h3><p>Return a named value at a path as JSON.</p><p>Block type: REPORTER. Opcode: <code>getJsonAtPath</code>. <a href="#block-getJsonAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr></tbody></table></div></article><article id="block-hasPath" class="block-reference-entry"><h3><code>structured data [NAME] has path [PATH]?</code></h3><p>Report whether a path exists in named structured data.</p><p>Block type: BOOLEAN. Opcode: <code>hasPath</code>. <a href="#block-hasPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr></tbody></table></div></article><article id="block-setJsonAtPath" class="block-reference-entry"><h3><code>set [NAME] at path [PATH] to JSON [VALUE]</code></h3><p>Immutably update a named value and replace its binding.</p><p>Block type: COMMAND. Opcode: <code>setJsonAtPath</code>. <a href="#block-setJsonAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr><tr><th scope="row"><code>VALUE</code></th><td>STRING</td><td><code>"Scratch"</code></td><td></td></tr></tbody></table></div></article><article id="block-deleteAtPath" class="block-reference-entry"><h3><code>delete path [PATH] from [NAME]</code></h3><p>Immutably delete a path and replace its named binding.</p><p>Block type: COMMAND. Opcode: <code>deleteAtPath</code>. <a href="#block-deleteAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr></tbody></table></div></article><article id="block-keysAtPath" class="block-reference-entry"><h3><code>keys in [NAME] at path [PATH]</code></h3><p>Return sorted object keys as JSON.</p><p>Block type: REPORTER. Opcode: <code>keysAtPath</code>. <a href="#block-keysAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$</code></td><td></td></tr></tbody></table></div></article><article id="block-lengthAtPath" class="block-reference-entry"><h3><code>length of array in [NAME] at path [PATH]</code></h3><p>Return the array length.</p><p>Block type: REPORTER. Opcode: <code>lengthAtPath</code>. <a href="#block-lengthAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$</code></td><td></td></tr></tbody></table></div></article><article id="block-forEachAtPath" class="block-reference-entry"><h3><code>for each in [NAME] at path [PATH] max [MAX]</code></h3><p>Iterate named data deterministically with a static maximum.</p><p>Block type: LOOP. Opcode: <code>forEachAtPath</code>. <a href="#block-forEachAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$</code></td><td></td></tr><tr><th scope="row"><code>MAX</code></th><td>NUMBER</td><td><code>100</code></td><td></td></tr></tbody></table></div
|
|
55
|
+
<article id="block-parseJson" class="block-reference-entry"><h3><code>parse JSON [TEXT] as [NAME]</code></h3><p>Parse JSON text into the target-local structured data namespace.</p><p>Block type: COMMAND. Opcode: <code>parseJson</code>. <a href="#block-parseJson">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>TEXT</code></th><td>STRING</td><td><code>{"name":"TurboWarp"}</code></td><td></td></tr><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-parseYaml" class="block-reference-entry"><h3><code>parse YAML [TEXT] as [NAME]</code></h3><p>Parse safe YAML text into the target-local structured data namespace.</p><p>Block type: COMMAND. Opcode: <code>parseYaml</code>. <a href="#block-parseYaml">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>TEXT</code></th><td>STRING</td><td><code>name: TurboWarp</code></td><td></td></tr><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-toJson" class="block-reference-entry"><h3><code>to JSON [NAME]</code></h3><p>Render named structured data as canonical JSON.</p><p>Block type: REPORTER. Opcode: <code>toJson</code>. <a href="#block-toJson">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-toYaml" class="block-reference-entry"><h3><code>to YAML [NAME]</code></h3><p>Render named structured data as deterministic YAML.</p><p>Block type: REPORTER. Opcode: <code>toYaml</code>. <a href="#block-toYaml">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-hasStructuredData" class="block-reference-entry"><h3><code>structured data [NAME] exists?</code></h3><p>Report whether the current target has named structured data.</p><p>Block type: BOOLEAN. Opcode: <code>hasStructuredData</code>. <a href="#block-hasStructuredData">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-deleteStructuredData" class="block-reference-entry"><h3><code>delete structured data [NAME]</code></h3><p>Delete named structured data from the current target.</p><p>Block type: COMMAND. Opcode: <code>deleteStructuredData</code>. <a href="#block-deleteStructuredData">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr></tbody></table></div></article><article id="block-getJsonAtPath" class="block-reference-entry"><h3><code>get JSON from [NAME] at path [PATH]</code></h3><p>Return a named value at a path as JSON.</p><p>Block type: REPORTER. Opcode: <code>getJsonAtPath</code>. <a href="#block-getJsonAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr></tbody></table></div></article><article id="block-hasPath" class="block-reference-entry"><h3><code>structured data [NAME] has path [PATH]?</code></h3><p>Report whether a path exists in named structured data.</p><p>Block type: BOOLEAN. Opcode: <code>hasPath</code>. <a href="#block-hasPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr></tbody></table></div></article><article id="block-setJsonAtPath" class="block-reference-entry"><h3><code>set [NAME] at path [PATH] to JSON [VALUE]</code></h3><p>Immutably update a named value and replace its binding.</p><p>Block type: COMMAND. Opcode: <code>setJsonAtPath</code>. <a href="#block-setJsonAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr><tr><th scope="row"><code>VALUE</code></th><td>STRING</td><td><code>"Scratch"</code></td><td></td></tr></tbody></table></div></article><article id="block-deleteAtPath" class="block-reference-entry"><h3><code>delete path [PATH] from [NAME]</code></h3><p>Immutably delete a path and replace its named binding.</p><p>Block type: COMMAND. Opcode: <code>deleteAtPath</code>. <a href="#block-deleteAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$.name</code></td><td></td></tr></tbody></table></div></article><article id="block-keysAtPath" class="block-reference-entry"><h3><code>keys in [NAME] at path [PATH]</code></h3><p>Return sorted object keys as JSON.</p><p>Block type: REPORTER. Opcode: <code>keysAtPath</code>. <a href="#block-keysAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$</code></td><td></td></tr></tbody></table></div></article><article id="block-lengthAtPath" class="block-reference-entry"><h3><code>length of array in [NAME] at path [PATH]</code></h3><p>Return the array length.</p><p>Block type: REPORTER. Opcode: <code>lengthAtPath</code>. <a href="#block-lengthAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$</code></td><td></td></tr></tbody></table></div></article><article id="block-forEachAtPath" class="block-reference-entry"><h3><code>for each in [NAME] at path [PATH] max [MAX]</code></h3><p>Iterate named data deterministically with a static maximum.</p><p>Block type: LOOP. Opcode: <code>forEachAtPath</code>. <a href="#block-forEachAtPath">Permanent link</a></p><div class="block-reference-table"><table><thead><tr><th>Argument</th><th>Type</th><th>Default value</th><th>Menu choices</th></tr></thead><tbody><tr><th scope="row"><code>NAME</code></th><td>STRING</td><td><code>data</code></td><td></td></tr><tr><th scope="row"><code>PATH</code></th><td>STRING</td><td><code>$</code></td><td></td></tr><tr><th scope="row"><code>MAX</code></th><td>NUMBER</td><td><code>100</code></td><td></td></tr></tbody></table></div><!-- BEGIN FIXED INPUT HELP --><p id="fixed-input-forEachAtPath-MAX" class="fixed-input-editor">MVP機能を有効にした場合だけ、MAXを整数1〜1000で編集します。入力途中・空白・非finiteな新値は保存できません。NAMEとPATHは変更しません。 GUIのDialogsとFixedInputsは起動時の既定OFFです。両方を有効にして再読込すると固定フォームが使えます。未変更のraw値を保存し直さず、接続reporterは評価しません。</p><!-- END FIXED INPUT HELP --></article><article id="block-currentKey" class="block-reference-entry"><h3><code>current key</code></h3><p>Return the current object key or array index string.</p><p>Block type: REPORTER. Opcode: <code>currentKey</code>. <a href="#block-currentKey">Permanent link</a></p><p>This block has no arguments.</p></article><article id="block-currentIndex" class="block-reference-entry"><h3><code>current index</code></h3><p>Return the zero-based iteration number.</p><p>Block type: REPORTER. Opcode: <code>currentIndex</code>. <a href="#block-currentIndex">Permanent link</a></p><p>This block has no arguments.</p></article><article id="block-currentValueJson" class="block-reference-entry"><h3><code>current value JSON</code></h3><p>Return the current iteration value as JSON.</p><p>Block type: REPORTER. Opcode: <code>currentValueJson</code>. <a href="#block-currentValueJson">Permanent link</a></p><p>This block has no arguments.</p></article>
|
|
56
56
|
<p><a href="https://github.com/kubohiroya/turbowarp-structured-data/blob/main/README.md">Repository guide and examples</a></p>
|
|
57
57
|
</section>
|
|
58
58
|
<!-- END COMPLETE BLOCK REFERENCE -->
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://kubohiroya.github.io/turbowarp-structured-data/schemas/block-editor-fixed-inputs.schema.json",
|
|
4
|
+
"$defs": {
|
|
5
|
+
"forEachAtPath": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"MAX": {
|
|
9
|
+
"type": "integer",
|
|
10
|
+
"minimum": 1,
|
|
11
|
+
"maximum": 1000
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"required": [
|
|
15
|
+
"MAX"
|
|
16
|
+
],
|
|
17
|
+
"additionalProperties": true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubohiroya/turbowarp-structured-data",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Named structured data with JSON/YAML codecs and deterministic path operations for TurboWarp.",
|
|
5
5
|
"author": "Hiroya Kubo <hiroya@cuc.ac.jp>",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"dist/",
|
|
28
28
|
"docs/",
|
|
29
29
|
"src/",
|
|
30
|
+
"schemas/",
|
|
30
31
|
"templates/",
|
|
31
32
|
"README.md",
|
|
32
33
|
"README.ja.md",
|
|
@@ -47,8 +48,8 @@
|
|
|
47
48
|
"build": "vite build",
|
|
48
49
|
"lint": "eslint src tests scripts vite.config.ts eslint.config.ts",
|
|
49
50
|
"test": "vitest run",
|
|
50
|
-
"docs": "node scripts/generate-readme.ts",
|
|
51
|
-
"docs:check": "node scripts/generate-readme.ts --check",
|
|
51
|
+
"docs": "node scripts/generate-readme.ts && node scripts/generate-fixed-input-docs.mjs",
|
|
52
|
+
"docs:check": "node scripts/generate-readme.ts --check && node scripts/generate-fixed-input-docs.mjs --check",
|
|
52
53
|
"template:readme": "node scripts/apply-readme-template.ts",
|
|
53
54
|
"repo:check": "node scripts/check-repo.ts",
|
|
54
55
|
"pack:check": "npm pack --dry-run --ignore-scripts",
|
|
@@ -57,9 +58,9 @@
|
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@eslint/js": "^9.39.5",
|
|
60
|
-
"@kubohiroya/turbowarp-extension-manifest": "0.3.
|
|
61
|
-
"@kubohiroya/turbowarp-named-data": "0.1
|
|
62
|
-
"@kubohiroya/vite-plugin-turbowarp-extension": "0.
|
|
61
|
+
"@kubohiroya/turbowarp-extension-manifest": "0.3.2",
|
|
62
|
+
"@kubohiroya/turbowarp-named-data": "0.3.1",
|
|
63
|
+
"@kubohiroya/vite-plugin-turbowarp-extension": "0.6.1",
|
|
63
64
|
"@types/node": "^24.13.3",
|
|
64
65
|
"eslint": "^9.39.5",
|
|
65
66
|
"jiti": "^2.7.0",
|
|
@@ -71,9 +72,15 @@
|
|
|
71
72
|
},
|
|
72
73
|
"dependencies": {
|
|
73
74
|
"yaml": "^2.9.1",
|
|
74
|
-
"@kubohiroya/turbowarp-extension-data-editor": "
|
|
75
|
+
"@kubohiroya/turbowarp-extension-data-editor": "0.2.1"
|
|
75
76
|
},
|
|
76
77
|
"peerDependencies": {
|
|
77
|
-
"@kubohiroya/turbowarp-named-data": "
|
|
78
|
+
"@kubohiroya/turbowarp-named-data": "0.3.1"
|
|
79
|
+
},
|
|
80
|
+
"gitHead": "7429d0707e0c46099fa89d09f456a43a29919395",
|
|
81
|
+
"x-turbowarp-source": {
|
|
82
|
+
"revision": "7429d0707e0c46099fa89d09f456a43a29919395",
|
|
83
|
+
"revisionRole": "base-commit",
|
|
84
|
+
"sourceState": "local-release-overlay"
|
|
78
85
|
}
|
|
79
86
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://kubohiroya.github.io/turbowarp-structured-data/schemas/block-editor-fixed-inputs.schema.json",
|
|
4
|
+
"$defs": {
|
|
5
|
+
"forEachAtPath": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"MAX": {
|
|
9
|
+
"type": "integer",
|
|
10
|
+
"minimum": 1,
|
|
11
|
+
"maximum": 1000
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"required": [
|
|
15
|
+
"MAX"
|
|
16
|
+
],
|
|
17
|
+
"additionalProperties": true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/extension.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {fixedInputEditorDefinitions, registerFixedInputEditors} from './fixed-input-editors.js';
|
|
1
2
|
import {sourceEditorDefinitions} from './editor-schema.js';
|
|
2
3
|
import {registerSourceEditors} from './source-editor.js';
|
|
3
4
|
import definitions from './block-definitions.json';
|
|
@@ -74,7 +75,10 @@ const blockDefinitions = definitions.blocks as readonly BlockDefinition[];
|
|
|
74
75
|
|
|
75
76
|
export class StructuredDataExtension implements TurboWarpExtension {
|
|
76
77
|
private readonly enabled: boolean;
|
|
78
|
+
private disposed = false;
|
|
79
|
+
private readonly releaseRuntimeListeners: () => void;
|
|
77
80
|
private readonly unregisterSourceEditors: () => void;
|
|
81
|
+
private readonly unregisterFixedInputEditors: () => void;
|
|
78
82
|
private registries = new WeakMap<object, Map<string, StructuredDataBinding>>();
|
|
79
83
|
private iterationStacks = new WeakMap<object, ActiveIteration[]>();
|
|
80
84
|
private nextRevision = 1;
|
|
@@ -89,6 +93,17 @@ export class StructuredDataExtension implements TurboWarpExtension {
|
|
|
89
93
|
) {
|
|
90
94
|
this.enabled = enabled;
|
|
91
95
|
this.unregisterSourceEditors = registerSourceEditors(Scratch, enabled ? sourceEditorDefinitions : []);
|
|
96
|
+
const runtime = Scratch.vm?.runtime;
|
|
97
|
+
const onDispose = () => {void this.dispose();};
|
|
98
|
+
const onStop = () => this.clearRuntimeState();
|
|
99
|
+
this.releaseRuntimeListeners = () => {
|
|
100
|
+
runtime?.off?.('RUNTIME_DISPOSED', onDispose);
|
|
101
|
+
runtime?.off?.('PROJECT_STOP_ALL', onStop);
|
|
102
|
+
};
|
|
103
|
+
let unregisterFixed = () => {};
|
|
104
|
+
try {
|
|
105
|
+
unregisterFixed = registerFixedInputEditors(Scratch, enabled ? fixedInputEditorDefinitions : []);
|
|
106
|
+
this.unregisterFixedInputEditors = unregisterFixed;
|
|
92
107
|
if (namedDataEnabled) {
|
|
93
108
|
this.namedDataProvider = new StructuredDataNamedDataProvider({
|
|
94
109
|
get: (target, name) => this.registries.get(target)?.get(name)
|
|
@@ -104,12 +119,18 @@ export class StructuredDataExtension implements TurboWarpExtension {
|
|
|
104
119
|
runtime,
|
|
105
120
|
this.namedDataRegistry
|
|
106
121
|
);
|
|
107
|
-
runtime.on?.('RUNTIME_DISPOSED',
|
|
108
|
-
void this.dispose();
|
|
109
|
-
});
|
|
122
|
+
runtime.on?.('RUNTIME_DISPOSED', onDispose);
|
|
110
123
|
}
|
|
111
124
|
}
|
|
112
|
-
|
|
125
|
+
runtime?.on?.('PROJECT_STOP_ALL', onStop);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
this.releaseRuntimeListeners();
|
|
128
|
+
unregisterFixed();
|
|
129
|
+
this.unregisterSourceEditors();
|
|
130
|
+
this.unbindNamedDataRegistryLifecycle?.();
|
|
131
|
+
void this.namedDataRegistration?.unregister().catch(() => {});
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
113
134
|
}
|
|
114
135
|
|
|
115
136
|
public getNamedDataProvider(): StructuredDataNamedDataProvider | undefined {
|
|
@@ -121,6 +142,10 @@ export class StructuredDataExtension implements TurboWarpExtension {
|
|
|
121
142
|
}
|
|
122
143
|
|
|
123
144
|
public async dispose(): Promise<void> {
|
|
145
|
+
if (this.disposed) return;
|
|
146
|
+
this.disposed = true;
|
|
147
|
+
this.releaseRuntimeListeners();
|
|
148
|
+
this.unregisterFixedInputEditors();
|
|
124
149
|
this.unregisterSourceEditors();
|
|
125
150
|
await this.namedDataRegistration?.unregister();
|
|
126
151
|
this.unbindNamedDataRegistryLifecycle?.();
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {parseFixedNumberInput} from '@kubohiroya/turbowarp-extension-data-editor';
|
|
2
|
+
import type {FixedInputEditorOptions} from '@kubohiroya/turbowarp-extension-data-editor';
|
|
3
|
+
import {extensionConfig} from './config.js';
|
|
4
|
+
import {fixedInputSchemaBundle} from './fixed-input-schema.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const fixedInputEditorDefinitions: readonly FixedInputEditorOptions[] = [{
|
|
8
|
+
apiVersion: 1, extensionId: extensionConfig.id, editorId: 'forEachAtPath-fixed-inputs',
|
|
9
|
+
opcodes: [`${extensionConfig.id}_forEachAtPath`],
|
|
10
|
+
contractId: 'turbowarp-structured-data:forEachAtPath.MAX', contractRevision: 'fixed-inputs-v1',
|
|
11
|
+
bindings: [{argument: 'MAX', schemaBundle: fixedInputSchemaBundle,
|
|
12
|
+
control: {kind: 'number', label: 'MAX'},
|
|
13
|
+
read(value) {
|
|
14
|
+
if (typeof value !== 'string' && typeof value !== 'number') throw new TypeError('Expected a literal maximum.');
|
|
15
|
+
if (typeof value === 'string' && value.trim() === '') throw new TypeError('Blank maximum stays readonly.');
|
|
16
|
+
// Existing nonempty finite Number aliases may project; no-op saving retains the exact raw token.
|
|
17
|
+
const number = Number(value);
|
|
18
|
+
if (!Number.isFinite(number)) throw new TypeError('Maximum must be finite.');
|
|
19
|
+
return number;
|
|
20
|
+
},
|
|
21
|
+
encode(value) {
|
|
22
|
+
const parsed = parseFixedNumberInput(value);
|
|
23
|
+
if (parsed.kind !== 'valid') throw new TypeError('Expected a finite numeric token.');
|
|
24
|
+
return parsed.token;
|
|
25
|
+
},
|
|
26
|
+
validateCandidate(value) {
|
|
27
|
+
const parsed = parseFixedNumberInput(value);
|
|
28
|
+
return parsed.kind === 'valid' && Number.isInteger(parsed.value) && parsed.value >= 1 && parsed.value <= 1000 ? []
|
|
29
|
+
: [{path: '/inputs/MAX', message: 'Maximum must be an integer from 1 to 1000.'}];
|
|
30
|
+
}
|
|
31
|
+
}],
|
|
32
|
+
validationContext: () => ({consumerId: extensionConfig.id, nowMs: Date.now(), settings: null})
|
|
33
|
+
}];
|
|
34
|
+
|
|
35
|
+
interface RuntimeLifetime {
|
|
36
|
+
on?: (event: string, listener: () => void) => void;
|
|
37
|
+
off?: (event: string, listener: () => void) => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Register metadata only; the GUI startup capability owns editor activation. */
|
|
41
|
+
export function registerFixedInputEditors(
|
|
42
|
+
scratch: unknown, definitions: readonly FixedInputEditorOptions[], runtimeOverride?: RuntimeLifetime
|
|
43
|
+
): () => void {
|
|
44
|
+
const host = scratch as {gui?: {blockEditors?: {apiVersion?: number;
|
|
45
|
+
registerFixedInputEditor?: (options: FixedInputEditorOptions) => () => void}};
|
|
46
|
+
vm?: {runtime?: RuntimeLifetime}};
|
|
47
|
+
const api = host.gui?.blockEditors;
|
|
48
|
+
if (!definitions.length || api?.apiVersion !== 1 || typeof api.registerFixedInputEditor !== 'function') return () => {};
|
|
49
|
+
const runtime = runtimeOverride ?? host.vm?.runtime;
|
|
50
|
+
const removers: (() => void)[] = [];
|
|
51
|
+
let active = true;
|
|
52
|
+
const dispose = () => {
|
|
53
|
+
if (!active) return;
|
|
54
|
+
active = false;
|
|
55
|
+
runtime?.off?.('RUNTIME_DISPOSED', dispose);
|
|
56
|
+
for (const remove of removers.splice(0).reverse()) remove();
|
|
57
|
+
};
|
|
58
|
+
try {
|
|
59
|
+
for (const definition of definitions) {
|
|
60
|
+
const remove = api.registerFixedInputEditor.call(api, definition);
|
|
61
|
+
if (typeof remove !== 'function') throw new TypeError('Invalid fixed input registration disposer.');
|
|
62
|
+
removers.push(remove);
|
|
63
|
+
}
|
|
64
|
+
runtime?.on?.('RUNTIME_DISPOSED', dispose);
|
|
65
|
+
} catch (error) {dispose(); throw error;}
|
|
66
|
+
return dispose;
|
|
67
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type {SchemaBundle} from '@kubohiroya/turbowarp-extension-data-editor/schema';
|
|
2
|
+
import document from '../schemas/block-editor-fixed-inputs.schema.json';
|
|
3
|
+
|
|
4
|
+
const source = {repository: 'turbowarp-structured-data', path: 'schemas/block-editor-fixed-inputs.schema.json',
|
|
5
|
+
symbol: '#/$defs/forEachAtPath/properties/MAX'};
|
|
6
|
+
|
|
7
|
+
/** The on-disk owner Schema is canonical; this is its single-field projection. */
|
|
8
|
+
export const fixedInputSchemaBundle: SchemaBundle = {
|
|
9
|
+
identity: {ownerId: 'turbowarp-structured-data', contractId: 'forEachAtPath.MAX', revision: 'fixed-inputs-v1', variantId: 'default'},
|
|
10
|
+
dialect: '2020-12',
|
|
11
|
+
root: {retrievalUri: 'https://kubohiroya.github.io/turbowarp-structured-data/schemas/forEachAtPath-MAX.schema.json',
|
|
12
|
+
document: document.$defs.forEachAtPath.properties.MAX, artifact: {role: 'canonical-schema', source}},
|
|
13
|
+
resources: [],
|
|
14
|
+
provenance: {canonicalSources: [source, {repository: 'turbowarp-structured-data', path: 'src/core.ts', symbol: 'iterationEntries'}],
|
|
15
|
+
generatedFiles: [{repository: 'turbowarp-structured-data', path: 'docs/schemas/block-editor-fixed-inputs.schema.json'}], referenceSchemas: [], generationSources: [{repository: 'turbowarp-structured-data', path: 'scripts/generate-fixed-input-docs.mjs'}]}
|
|
16
|
+
};
|
package/templates/README.ja.md
CHANGED
|
@@ -181,3 +181,16 @@ release consistency checkでは、exact-version README/CDN例に加え、`docs
|
|
|
181
181
|
|
|
182
182
|
third-party componentを含む場合は
|
|
183
183
|
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md)に記載します。
|
|
184
|
+
|
|
185
|
+
## 固定引数の編集フォーム(S3-4)
|
|
186
|
+
|
|
187
|
+
共通エディターの起動時フラグ `blockEditorFixedInputs` とDialogsがONのGUIでは、`forEachAtPath` の `MAX` だけを固定フォームとして登録します。旧GUI・フラグOFFでは追加登録を行いません。Schemaの正本は `schemas/block-editor-fixed-inputs.schema.json#/$defs/forEachAtPath/properties/MAX`、codecと登録は `src/fixed-input-editors.ts` です。既存raw値・未変更alias・未知enumは無操作保存で書き換えず、reporterを評価しません。明示変更だけを検査し、他の引数やブロック宣言、保存形式を変更しません。
|
|
188
|
+
|
|
189
|
+
MAXは整数1〜1000です。新しい入力には共通の有限数値token規則も適用し、途中入力を保存しません。MVP flagがOFFなら登録せず、NAME/PATH・staticLiteral由来の接続可否を変更しません。
|
|
190
|
+
|
|
191
|
+
登録はoptional API(apiVersion:1)に限定し、RUNTIME_DISPOSED/明示disposeで解除します。起動フラグOFF+再読込で従来経路へ切り戻せます。依存を戻す場合はmanifest/lock/実解決を一組で復旧します。npm公開や後続段階の動的候補は含みません。
|
|
192
|
+
|
|
193
|
+
Schemaが記述する契約の根拠は実getInfoの宣言と既存の純粋なruntime変換です。SchemaBundleのretrievalUriはこのローカル文書の識別子であり、URL配信済み・HTTP取得によるref解決を意味しません。Schemaは同梱文書だけでcompileします。
|
|
194
|
+
既存MAXの非空finiteなNumber alias(例`001`・`+1`・`0x10`)はNumberによる表示投影だけを行い、無変更rawを保存し直しません。空白・非finite・投影不能値はreadonlyとし、0/defaultを補いません。新しい入力にはこれらaliasを許可せずNP-finite-new-input-v1を適用します。
|
|
195
|
+
|
|
196
|
+
登録は拡張インスタンスの構築時に存在する任意の editor API を使用します。後からの API 追加や差し替えには自動追従しません。起動設定を変更した場合は GUI を再読み込みし、拡張インスタンスを再構築してください。
|
package/templates/README.md
CHANGED
|
@@ -196,3 +196,16 @@ site and `blockIconURI` remains a `data:image/svg+xml;base64,...` URI.
|
|
|
196
196
|
|
|
197
197
|
Third-party components, when present, are listed in
|
|
198
198
|
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md).
|
|
199
|
+
|
|
200
|
+
## 固定引数の編集フォーム(S3-4)
|
|
201
|
+
|
|
202
|
+
共通エディターの起動時フラグ `blockEditorFixedInputs` とDialogsがONのGUIでは、`forEachAtPath` の `MAX` だけを固定フォームとして登録します。旧GUI・フラグOFFでは追加登録を行いません。Schemaの正本は `schemas/block-editor-fixed-inputs.schema.json#/$defs/forEachAtPath/properties/MAX`、codecと登録は `src/fixed-input-editors.ts` です。既存raw値・未変更alias・未知enumは無操作保存で書き換えず、reporterを評価しません。明示変更だけを検査し、他の引数やブロック宣言、保存形式を変更しません。
|
|
203
|
+
|
|
204
|
+
MAXは整数1〜1000です。新しい入力には共通の有限数値token規則も適用し、途中入力を保存しません。MVP flagがOFFなら登録せず、NAME/PATH・staticLiteral由来の接続可否を変更しません。
|
|
205
|
+
|
|
206
|
+
登録はoptional API(apiVersion:1)に限定し、RUNTIME_DISPOSED/明示disposeで解除します。起動フラグOFF+再読込で従来経路へ切り戻せます。依存を戻す場合はmanifest/lock/実解決を一組で復旧します。npm公開や後続段階の動的候補は含みません。
|
|
207
|
+
|
|
208
|
+
Schemaが記述する契約の根拠は実getInfoの宣言と既存の純粋なruntime変換です。SchemaBundleのretrievalUriはこのローカル文書の識別子であり、URL配信済み・HTTP取得によるref解決を意味しません。Schemaは同梱文書だけでcompileします。
|
|
209
|
+
既存MAXの非空finiteなNumber alias(例`001`・`+1`・`0x10`)はNumberによる表示投影だけを行い、無変更rawを保存し直しません。空白・非finite・投影不能値はreadonlyとし、0/defaultを補いません。新しい入力にはこれらaliasを許可せずNP-finite-new-input-v1を適用します。
|
|
210
|
+
|
|
211
|
+
Registration uses the optional editor API available when the extension instance is constructed. Adding or replacing that API later is not followed automatically; reload the GUI and reconstruct the extension instance after changing the startup configuration.
|