@kubohiroya/turbowarp-extension-loader 0.5.0 → 0.5.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 +2 -1
- package/README.md +2 -1
- package/dist/packager.js +4 -1
- package/dist/project-authoring.js +5 -2
- package/dist/project-catalog.js +5 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -218,7 +218,8 @@ Manifest は `uri` を持てます。その作品をダウンロードできる
|
|
|
218
218
|
{"schemaVersion": 1, "uri": "https://example.test/editor/turbowarp-plus-projects/66/66aa/0193f0a1-2b3c-7d4e-8f01-2233445566aa.sb3", "extensions": []}
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
1つの作品に1つの URI
|
|
221
|
+
1つの作品に1つの URI。何度編集しても変わりません。拡張を足したり形式を変えたりすると Manifest は
|
|
222
|
+
組み直されますが、住所はその向こう側で保たれます。だから指紋ではなく住所なのです。指紋は保存
|
|
222
223
|
するたびに変わるので、ブラウザーのキャッシュも開く人の選択の記録も、触るたびに同じ作品を別名で
|
|
223
224
|
綴じてしまいます。住所は中身が変わっても変わりません。
|
|
224
225
|
|
package/README.md
CHANGED
|
@@ -220,7 +220,8 @@ identifies it.
|
|
|
220
220
|
{"schemaVersion": 1, "uri": "https://example.test/editor/turbowarp-plus-projects/66/66aa/0193f0a1-2b3c-7d4e-8f01-2233445566aa.sb3", "extensions": []}
|
|
221
221
|
```
|
|
222
222
|
|
|
223
|
-
One work, one URI, across every edit
|
|
223
|
+
One work, one URI, across every edit — including the edits that change its extensions, which
|
|
224
|
+
rebuild the manifest around it. That is why it is an address and not a fingerprint: a
|
|
224
225
|
fingerprint changes on every save, so a browser cache and a record of what the opener chose would
|
|
225
226
|
file one work under a new name each time it was touched. An address does not change when the bytes
|
|
226
227
|
do.
|
package/dist/packager.js
CHANGED
|
@@ -81,7 +81,10 @@ export async function convertProjectSources(input, ports, { zip: Zip, targets =
|
|
|
81
81
|
for (const id of Object.keys(targets))
|
|
82
82
|
if (!records.some(record => record.id === id))
|
|
83
83
|
fail('UNKNOWN_EXTENSION', `Unknown conversion target ${id}`);
|
|
84
|
-
|
|
84
|
+
// The project keeps its address through a conversion: it is the same work, served from the
|
|
85
|
+
// same place, however its extensions are now held.
|
|
86
|
+
const manifest = validateManifest({ schemaVersion: 1,
|
|
87
|
+
...(prepared.manifest.uri === undefined ? {} : { uri: prepared.manifest.uri }), extensions });
|
|
85
88
|
const lock = Object.freeze({ schemaVersion: 1, previousLock: project.turboWarpPlusLock ?? null, extensions: Object.freeze(lockEntries) });
|
|
86
89
|
project.turboWarpPlus = manifest;
|
|
87
90
|
project.turboWarpPlusLock = lock;
|
|
@@ -94,10 +94,13 @@ export async function prepareExtensionAddition(input, request, ports, { zip: Zip
|
|
|
94
94
|
if (project.extensionURLs !== undefined && !plainObject(project.extensionURLs))
|
|
95
95
|
fail('INVALID_PROJECT', 'Project extensionURLs must be an object');
|
|
96
96
|
const previous = prepared.manifest?.extensions || [];
|
|
97
|
+
// Carried through every rebuild below: an address that changed when an extension was
|
|
98
|
+
// added would not be an address.
|
|
99
|
+
const carried = prepared.manifest?.uri === undefined ? {} : { uri: prepared.manifest.uri };
|
|
97
100
|
if (previous.some(spec => spec.id === draft.id) || (project.extensions || []).includes(draft.id) ||
|
|
98
101
|
Object.hasOwn(project.extensionURLs || {}, draft.id))
|
|
99
102
|
fail('DUPLICATE_EXTENSION', 'This extension ID already belongs to the project', draft.id);
|
|
100
|
-
validateManifest({ schemaVersion: 1, extensions: [...previous, draft] }, loaderOptions);
|
|
103
|
+
validateManifest({ schemaVersion: 1, ...carried, extensions: [...previous, draft] }, loaderOptions);
|
|
101
104
|
if (draft.source.type === 'embedded-file' && Object.hasOwn(files, draft.source.path)) {
|
|
102
105
|
fail('SOURCE_PATH_COLLISION', 'The embedded path already exists in this project', draft.id);
|
|
103
106
|
}
|
|
@@ -128,7 +131,7 @@ export async function prepareExtensionAddition(input, request, ports, { zip: Zip
|
|
|
128
131
|
}
|
|
129
132
|
const verified = new Uint8Array(bytes);
|
|
130
133
|
const sha256 = await wait(() => digest(verified));
|
|
131
|
-
const manifest = validateManifest({ schemaVersion: 1, extensions: [...previous, { ...draft, sha256 }] }, loaderOptions);
|
|
134
|
+
const manifest = validateManifest({ schemaVersion: 1, ...carried, extensions: [...previous, { ...draft, sha256 }] }, loaderOptions);
|
|
132
135
|
const spec = manifest.extensions.find(item => item.id === draft.id);
|
|
133
136
|
project.turboWarpPlus = manifest;
|
|
134
137
|
project.extensions = [...(project.extensions || []), spec.id];
|
package/dist/project-catalog.js
CHANGED
|
@@ -173,7 +173,11 @@ export async function prepareCatalogExtensionChanges(input, requests, ports, { z
|
|
|
173
173
|
...(old?.publisher ? { publisher: old.publisher } : {}),
|
|
174
174
|
capabilities: old?.capabilities || [], dependencies: choice.dependencies });
|
|
175
175
|
}
|
|
176
|
-
|
|
176
|
+
// The project's own address survives a change to its extensions. Rebuilding the manifest
|
|
177
|
+
// without it would file the same work under a new name the next time it was saved, which
|
|
178
|
+
// is the one thing an address is for.
|
|
179
|
+
const manifest = validateManifest({ schemaVersion: 1, ...(prepared.manifest?.uri === undefined ?
|
|
180
|
+
{} : { uri: prepared.manifest.uri }), extensions: [...extensions.values()] }, loaderOptions);
|
|
177
181
|
for (const spec of manifest.extensions)
|
|
178
182
|
if (spec.source.type === 'embedded-file')
|
|
179
183
|
replacedPaths.delete(spec.source.path);
|