@underpostnet/cyberia 3.3.73 → 3.3.77
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/.env.example +17 -5
- package/.github/workflows/coverall.cyberia.ci.yml +10 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
- package/.github/workflows/engine-cyberia.ci.yml +1 -1
- package/.github/workflows/publish.cyberia.ci.yml +44 -0
- package/AGENTS.md +61 -12
- package/CHANGELOG.md +159 -161
- package/CLI-HELP.md +20 -13
- package/Dockerfile +1 -1
- package/Dockerfile.dev +1 -1
- package/Dockerfile.test +2 -2
- package/README.md +28 -28
- package/bin/build.js +96 -21
- package/bin/cyberia.js +1247 -1373
- package/bin/index.js +1247 -1373
- package/compose.env +17 -5
- package/conf.js +7 -4
- package/deploy/cyberia-client/deploy.sh +10 -11
- package/deploy/cyberia-client/package.sh +0 -1
- package/deploy/cyberia-client/state.sh +3 -2
- package/deploy/cyberia-server/deploy.sh +10 -11
- package/deploy/cyberia-server/package.sh +0 -1
- package/deploy/cyberia-server/state.sh +3 -2
- package/deploy/dd-cyberia/deploy.sh +5 -5
- package/deploy/dd-cyberia/init.sh +15 -14
- package/deploy/dd-cyberia/package.sh +0 -1
- package/deploy/dd-cyberia/state.sh +2 -2
- package/deploy/dd-cyberia/sync-deploy.sh +139 -75
- package/deploy/lib/config.sh +29 -0
- package/deploy/lib/github-actions-logging.sh +92 -76
- package/deploy/lib/host.sh +28 -19
- package/deploy/lib/state.sh +4 -1
- package/deploy/pwa-microservices-template/deploy.sh +10 -8
- package/deploy/release/deploy.sh +0 -2
- package/deployment.yaml +1 -1
- package/docker-compose.yml +23 -17
- package/docs/coverage/cyberia/api/cyberia-instance/cyberia-fallback-capture.js.html +1591 -0
- package/docs/coverage/cyberia/api/cyberia-instance/index.html +116 -0
- package/docs/coverage/cyberia/api/cyberia-server-defaults/cyberia-server-defaults.js.html +4138 -0
- package/docs/coverage/cyberia/api/cyberia-server-defaults/index.html +116 -0
- package/docs/coverage/cyberia/api/object-layer/index.html +116 -0
- package/docs/coverage/cyberia/api/object-layer/object-layer.model.js.html +1393 -0
- package/docs/coverage/cyberia/base.css +362 -0
- package/docs/coverage/cyberia/block-navigation.js +82 -0
- package/docs/coverage/cyberia/favicon.png +0 -0
- package/docs/coverage/cyberia/index.html +161 -0
- package/docs/coverage/cyberia/prettify.css +101 -0
- package/docs/coverage/cyberia/prettify.js +937 -0
- package/docs/coverage/cyberia/projects/cyberia/atlas-sprite-sheet-generator.js.html +1315 -0
- package/docs/coverage/cyberia/projects/cyberia/index.html +176 -0
- package/docs/coverage/cyberia/projects/cyberia/instance-backup.js.html +715 -0
- package/docs/coverage/cyberia/projects/cyberia/instance-data.js.html +2182 -0
- package/docs/coverage/cyberia/projects/cyberia/shape-generator.js.html +3265 -0
- package/docs/coverage/cyberia/projects/cyberia/stat-balance.js.html +328 -0
- package/docs/coverage/cyberia/sort-arrow-sprite.png +0 -0
- package/docs/coverage/cyberia/sorter.js +205 -0
- package/hardhat/package-lock.json +2 -2
- package/hardhat/package.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/mongo-express/deployment.yaml +46 -27
- package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
- package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
- package/manifests/deployment/mongo-express/service.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
- package/package.json +19 -17
- package/scripts/test-monitor.sh +3 -3
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +14 -9
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +88 -184
- package/src/api/cyberia-action/cyberia-action.router.js +2 -2
- package/src/api/cyberia-action/cyberia-action.service.js +3 -4
- package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
- package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
- package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
- package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -3
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +12 -34
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +15 -32
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +1 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +16 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +466 -3
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +87 -51
- package/src/api/cyberia-instance/cyberia-fallback-world.js +21 -40
- package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +34 -141
- package/src/api/cyberia-instance/cyberia-instance.controller.js +1 -4
- package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
- package/src/api/cyberia-instance/cyberia-instance.router.js +3 -16
- package/src/api/cyberia-instance/cyberia-instance.service.js +3 -43
- package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +74 -1
- package/src/api/cyberia-map/cyberia-map.service.js +6 -2
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +3 -3
- package/src/api/cyberia-quest/cyberia-quest.service.js +3 -3
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -188
- package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
- package/src/api/file/file.ref.js +153 -0
- package/src/api/file/file.ref.json +11 -2
- package/src/api/object-layer/object-layer.model.js +47 -12
- package/src/api/object-layer/object-layer.router.js +10 -3
- package/src/api/object-layer/object-layer.service.js +113 -120
- package/src/cli/app.js +12 -1
- package/src/cli/client.js +2 -2
- package/src/cli/cluster.js +80 -18
- package/src/cli/deploy.js +215 -34
- package/src/cli/docker-compose.js +1 -1
- package/src/cli/fs-selection.js +115 -0
- package/src/cli/fs.js +158 -342
- package/src/cli/index.js +22 -10
- package/src/cli/release.js +3 -1
- package/src/cli/repository.js +35 -9
- package/src/cli/run.js +80 -199
- package/src/cli/test.js +4 -0
- package/src/cli/wireguard.js +32 -31
- package/src/client/components/core/Badge.js +0 -1
- package/src/client/components/core/CssCore.js +8 -1
- package/src/client/components/core/Docs.js +77 -100
- package/src/client/components/core/Modal.js +77 -23
- package/src/client/components/core/ToolTip.js +15 -0
- package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +0 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
- package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
- package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
- package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
- package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
- package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +0 -34
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +0 -4
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
- package/src/client/components/default/AppShellDefault.js +1 -4
- package/src/client/components/itemledger/AppShellItemledger.js +0 -2
- package/src/client/components/underpost/AppShellUnderpost.js +1 -1
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +280 -24
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
- package/src/client/public/cyberia-docs/CYBERIA.md +28 -28
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
- package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
- package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
- package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -10
- package/src/client/services/object-layer/object-layer.service.js +3 -1
- package/src/client/ssr/views/Cyberia404.js +3 -3
- package/src/client-builder/client-build-docs.js +52 -52
- package/src/client-builder/client-build.js +67 -44
- package/src/client-builder/client-bundle.js +347 -0
- package/src/db/mongo/MongoExpress.js +187 -0
- package/src/grpc/cyberia/grpc-server.js +5 -7
- package/src/index.js +1 -1
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +143 -146
- package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
- package/src/projects/cyberia/besu-genesis-generator.js +5 -14
- package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
- package/src/projects/cyberia/catalog-cyberia.js +3 -2
- package/src/projects/cyberia/gemini-client.js +3 -3
- package/src/projects/cyberia/generate-saga.js +4 -11
- package/src/projects/cyberia/hot-reload-trigger.js +17 -28
- package/src/projects/cyberia/instance-backup.js +210 -0
- package/src/projects/cyberia/instance-data.js +177 -257
- package/src/projects/cyberia/map-preview-generator.js +32 -68
- package/src/projects/cyberia/object-layer.js +152 -319
- package/src/projects/cyberia/seed-audio.js +139 -0
- package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
- package/src/projects/cyberia/semantic-layer-generator.js +2 -18
- package/src/projects/cyberia/stat-balance.js +81 -0
- package/src/projects/cyberia/stat-commands.js +23 -0
- package/src/projects/cyberia/stat-contract-generator.js +101 -0
- package/src/runtime/cyberia-client/Dockerfile +8 -4
- package/src/runtime/cyberia-client/Dockerfile.dev +5 -2
- package/src/runtime/cyberia-server/Dockerfile +9 -2
- package/src/runtime/cyberia-server/Dockerfile.dev +8 -1
- package/src/runtime/engine-cyberia/Dockerfile +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.test +2 -2
- package/src/runtime/engine-cyberia/compose.env +17 -5
- package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
- package/src/server/build/coverage.js +113 -42
- package/src/server/build/package.js +55 -12
- package/src/server/build/testing.js +59 -9
- package/src/server/network/middlewares.js +8 -2
- package/src/server/network/underpost-gateway.js +113 -14
- package/src/server/ops/logger.js +70 -35
- package/src/server/runtime/conf.js +40 -9
- package/src/server/runtime/start.js +11 -2
- package/src/server/storage/data-query.js +16 -0
- package/src/server/storage/downloader.js +62 -14
- package/src/server/storage/zip.js +153 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
- package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +34 -0
- package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-defaults.test.js +16 -22
- package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
- package/test/integration/app/cyberia/cyberia-load.test.js +6 -7
- package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
- package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +87 -2
- package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
- package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
- package/test/integration/app/cyberia/seed-audio.test.js +275 -0
- package/test/integration/infra/2-network/wireguard-cli.test.js +33 -9
- package/test/integration/infra/2-network/wireguard-edge.test.js +58 -18
- package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
- package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
- package/test/integration/infra/4-ingress/underpost-ingress.test.js +1 -1
- package/test/unit/catalog.test.js +13 -2
- package/test/unit/client-build-docs.test.js +97 -70
- package/test/unit/client-bundle.test.js +313 -0
- package/test/unit/conf-resolution.test.js +58 -7
- package/test/unit/coverage-artifact.test.js +120 -29
- package/test/unit/cyberia/instance-backup.test.js +183 -0
- package/test/unit/cyberia/instance-data.test.js +314 -0
- package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
- package/test/unit/cyberia/publish-workflow.test.js +22 -0
- package/test/unit/cyberia/stat-balance.test.js +69 -0
- package/test/unit/deploy-legacy-gateway-sweep.test.js +63 -0
- package/test/unit/deploy-log-table.test.js +76 -5
- package/test/unit/downloader-integrity.test.js +98 -0
- package/test/unit/file-reference-registry.test.js +141 -0
- package/test/unit/fs-storage-paths.test.js +596 -0
- package/test/unit/gateway-pod-fetch.test.js +95 -0
- package/test/unit/letsencrypt-issuer.test.js +101 -0
- package/test/unit/logger-redaction.test.js +29 -0
- package/test/unit/package.test.js +70 -16
- package/test/unit/prepare-host.test.js +84 -1
- package/test/unit/release-bump.test.js +3 -1
- package/test/unit/start-options.test.js +12 -0
- package/test/unit/test-tiers.test.js +27 -0
- package/test/unit/zip-archive.test.js +142 -0
- package/vitest.config.js +11 -3
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
|
@@ -11,9 +11,14 @@ import { PNG } from 'pngjs';
|
|
|
11
11
|
import sharp from 'sharp';
|
|
12
12
|
import { Jimp, intToRGBA, rgbaToInt } from 'jimp';
|
|
13
13
|
import { computeObjectLayerSha256 } from '../../api/object-layer/object-layer.model.js';
|
|
14
|
+
import { createPinRecord } from '../../api/ipfs/ipfs.service.js';
|
|
15
|
+
import { AtlasSpriteSheetStore } from './atlas-sprite-sheet-store.js';
|
|
16
|
+
import { IpfsClient } from './ipfs-client.js';
|
|
14
17
|
import { range } from '../../client/components/core/CommonJs.js';
|
|
15
18
|
import {
|
|
16
19
|
generateRandomStats,
|
|
20
|
+
validateStats,
|
|
21
|
+
STAT_CONTRACT_VERSION,
|
|
17
22
|
getKeyframeDirectionsByCode,
|
|
18
23
|
OBJECT_LAYER_DIRECTION_NAME_TO_CODE,
|
|
19
24
|
} from '../../client/components/cyberia/SharedDefaultsCyberia.js';
|
|
@@ -65,12 +70,10 @@ const logger = loggerFactory(import.meta);
|
|
|
65
70
|
*/
|
|
66
71
|
|
|
67
72
|
/**
|
|
68
|
-
* @typedef {Object}
|
|
69
|
-
* @property {boolean} [generateAtlas=true] - Whether to generate the atlas sprite sheet
|
|
70
|
-
* @property {
|
|
71
|
-
* @property {Object} [
|
|
72
|
-
* @property {Object} [atlasServiceContext.res] - Express-like response object.
|
|
73
|
-
* @property {Object} [atlasServiceContext.options] - Server options (host, path).
|
|
73
|
+
* @typedef {Object} PersistDocumentsOptions
|
|
74
|
+
* @property {boolean} [generateAtlas=true] - Whether to generate the atlas sprite sheet.
|
|
75
|
+
* @property {number} [upscaleFactor] - Pixels per cell of the human-resolution atlas render.
|
|
76
|
+
* @property {Object} [options] - Router options ({ host, path }) for model lookup.
|
|
74
77
|
* @memberof CyberiaObjectLayer
|
|
75
78
|
*/
|
|
76
79
|
|
|
@@ -342,6 +345,18 @@ export class ObjectLayerEngine {
|
|
|
342
345
|
* @returns {Promise<BuildFromDirectoryResult>} The assembled render frames data and object layer data.
|
|
343
346
|
* @memberof CyberiaObjectLayer
|
|
344
347
|
*/
|
|
348
|
+
static objectLayerDataFactory({ metadata, objectLayerType, objectLayerId }) {
|
|
349
|
+
const item = { id: objectLayerId, type: objectLayerType, description: '', activable: true };
|
|
350
|
+
if (!metadata?.data) return { data: { item, stats: generateRandomStats(), ledger: { type: 'OFF_CHAIN' } } };
|
|
351
|
+
return {
|
|
352
|
+
data: {
|
|
353
|
+
item: metadata.data.item || item,
|
|
354
|
+
stats: validateStats(metadata.data.stats ?? generateRandomStats()),
|
|
355
|
+
ledger: metadata.data.ledger || { type: 'OFF_CHAIN' },
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
345
360
|
static async buildObjectLayerDataFromDirectory({ folder, objectLayerType, objectLayerId, metadataOverride = null }) {
|
|
346
361
|
let metadata = metadataOverride;
|
|
347
362
|
|
|
@@ -356,11 +371,21 @@ export class ObjectLayerEngine {
|
|
|
356
371
|
// Build objectLayerRenderFramesData
|
|
357
372
|
let objectLayerRenderFramesData;
|
|
358
373
|
if (metadata && metadata.objectLayerRenderFramesData) {
|
|
374
|
+
// The editor states each frame cell for cell, with its own width and height. The PNGs
|
|
375
|
+
// beside it are what the client serves, not a source to re-derive the cells from: a
|
|
376
|
+
// decode has to guess the cell size, and a guess resamples every frame it is wrong for.
|
|
377
|
+
const { frames, colors, frame_duration } = metadata.objectLayerRenderFramesData;
|
|
378
|
+
const authored = frames && colors && Object.values(frames).some((direction) => direction?.length > 0);
|
|
359
379
|
objectLayerRenderFramesData = {
|
|
360
|
-
frame_duration:
|
|
361
|
-
frames: {},
|
|
362
|
-
colors: [],
|
|
380
|
+
frame_duration: frame_duration || 250,
|
|
381
|
+
frames: authored ? frames : {},
|
|
382
|
+
colors: authored ? colors : [],
|
|
363
383
|
};
|
|
384
|
+
if (authored)
|
|
385
|
+
return {
|
|
386
|
+
objectLayerRenderFramesData,
|
|
387
|
+
objectLayerData: ObjectLayerEngine.objectLayerDataFactory({ metadata, objectLayerType, objectLayerId }),
|
|
388
|
+
};
|
|
364
389
|
} else if (metadata && metadata.data && metadata.data.render) {
|
|
365
390
|
objectLayerRenderFramesData = {
|
|
366
391
|
frame_duration: metadata.data.render.frame_duration || 250,
|
|
@@ -375,35 +400,7 @@ export class ObjectLayerEngine {
|
|
|
375
400
|
};
|
|
376
401
|
}
|
|
377
402
|
|
|
378
|
-
|
|
379
|
-
let objectLayerData;
|
|
380
|
-
if (metadata && metadata.data) {
|
|
381
|
-
objectLayerData = {
|
|
382
|
-
data: {
|
|
383
|
-
item: metadata.data.item || {
|
|
384
|
-
id: objectLayerId,
|
|
385
|
-
type: objectLayerType,
|
|
386
|
-
description: '',
|
|
387
|
-
activable: true,
|
|
388
|
-
},
|
|
389
|
-
stats: metadata.data.stats || generateRandomStats(),
|
|
390
|
-
ledger: metadata.data.ledger || { type: 'OFF_CHAIN' },
|
|
391
|
-
},
|
|
392
|
-
};
|
|
393
|
-
} else {
|
|
394
|
-
objectLayerData = {
|
|
395
|
-
data: {
|
|
396
|
-
item: {
|
|
397
|
-
id: objectLayerId,
|
|
398
|
-
type: objectLayerType,
|
|
399
|
-
description: '',
|
|
400
|
-
activable: true,
|
|
401
|
-
},
|
|
402
|
-
stats: generateRandomStats(),
|
|
403
|
-
ledger: { type: 'OFF_CHAIN' },
|
|
404
|
-
},
|
|
405
|
-
};
|
|
406
|
-
}
|
|
403
|
+
const objectLayerData = ObjectLayerEngine.objectLayerDataFactory({ metadata, objectLayerType, objectLayerId });
|
|
407
404
|
|
|
408
405
|
// Process all PNG files from direction sub-folders
|
|
409
406
|
if (fs.existsSync(folder)) {
|
|
@@ -550,13 +547,12 @@ export class ObjectLayerEngine {
|
|
|
550
547
|
}
|
|
551
548
|
|
|
552
549
|
/**
|
|
553
|
-
*
|
|
554
|
-
* provided data, with cut-over consistency: all CIDs (atlas PNG, atlas metadata, data JSON)
|
|
555
|
-
* are computed and pinned to IPFS BEFORE the ObjectLayer document is created or updated in
|
|
556
|
-
* MongoDB, so the object layer is never visible in queries with empty CIDs.
|
|
550
|
+
* Writes an object layer and its render frames, keyed by `data.item.id`.
|
|
557
551
|
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
552
|
+
* Cut-over consistency: a new ObjectLayerRenderFrames is created, then the atlas
|
|
553
|
+
* and every CID are staged before the live document is touched. The single
|
|
554
|
+
* write lands through {@link ObjectLayerModel.upsertByItemId}, so one item id
|
|
555
|
+
* always resolves to one document, whether it is new or already stored.
|
|
560
556
|
*
|
|
561
557
|
* @static
|
|
562
558
|
* @param {Object} params - Parameters.
|
|
@@ -564,211 +560,83 @@ export class ObjectLayerEngine {
|
|
|
564
560
|
* @param {Object} params.ObjectLayerRenderFrames - Mongoose ObjectLayerRenderFrames model.
|
|
565
561
|
* @param {ObjectLayerRenderFramesData} params.objectLayerRenderFramesData - Render frames payload.
|
|
566
562
|
* @param {Object} params.objectLayerData - Object layer payload (must include `data`).
|
|
567
|
-
* @param {
|
|
563
|
+
* @param {PersistDocumentsOptions} [params.persistOptions={}] - Atlas generation and IPFS options.
|
|
568
564
|
* @returns {Promise<CreateDocumentsResult>} The persisted documents.
|
|
569
565
|
* @memberof CyberiaObjectLayer
|
|
570
566
|
*/
|
|
571
|
-
static async
|
|
567
|
+
static async persistObjectLayerDocuments({
|
|
572
568
|
ObjectLayer,
|
|
573
569
|
ObjectLayerRenderFrames,
|
|
574
570
|
objectLayerRenderFramesData,
|
|
575
571
|
objectLayerData,
|
|
576
|
-
|
|
572
|
+
persistOptions = {},
|
|
577
573
|
}) {
|
|
578
|
-
|
|
574
|
+
objectLayerData.data.stats = validateStats(objectLayerData.data.stats);
|
|
575
|
+
objectLayerData.statContractVersion = STAT_CONTRACT_VERSION;
|
|
576
|
+
const { generateAtlas = true, upscaleFactor, options } = persistOptions;
|
|
577
|
+
const itemId = objectLayerData.data.item.id;
|
|
579
578
|
|
|
580
|
-
|
|
581
|
-
const
|
|
579
|
+
const existing = await ObjectLayer.findByItemId(itemId);
|
|
580
|
+
const oldRenderFramesId = existing?.objectLayerRenderFramesId;
|
|
582
581
|
|
|
583
|
-
|
|
582
|
+
const objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.create(objectLayerRenderFramesData);
|
|
584
583
|
objectLayerData.objectLayerRenderFramesId = objectLayerRenderFramesDoc._id;
|
|
585
584
|
if (!objectLayerData.data.render) objectLayerData.data.render = {};
|
|
586
585
|
objectLayerData.data.render.cid = '';
|
|
587
586
|
objectLayerData.data.render.metadataCid = '';
|
|
588
587
|
|
|
589
|
-
|
|
590
|
-
if (generateAtlas && atlasServiceContext) {
|
|
591
|
-
const {
|
|
592
|
-
req,
|
|
593
|
-
res,
|
|
594
|
-
options,
|
|
595
|
-
AtlasSpriteSheetService,
|
|
596
|
-
IpfsClient: ipfsClient,
|
|
597
|
-
createPinRecord,
|
|
598
|
-
} = atlasServiceContext;
|
|
599
|
-
|
|
588
|
+
if (generateAtlas) {
|
|
600
589
|
try {
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
const result = await AtlasSpriteSheetService.generate(
|
|
606
|
-
{ objectLayer: stagingOL, auth: req ? req.auth : undefined },
|
|
607
|
-
res,
|
|
590
|
+
const { atlasDoc, atlasCid, atlasMetadataCid } = await AtlasSpriteSheetStore.persist({
|
|
591
|
+
itemKey: itemId,
|
|
592
|
+
objectLayerRenderFrames: objectLayerRenderFramesDoc,
|
|
593
|
+
upscaleFactor,
|
|
608
594
|
options,
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
objectLayerData.data.render.
|
|
612
|
-
objectLayerData.
|
|
613
|
-
objectLayerData.atlasSpriteSheetId = result.atlasDoc._id;
|
|
595
|
+
});
|
|
596
|
+
objectLayerData.data.render.cid = atlasCid;
|
|
597
|
+
objectLayerData.data.render.metadataCid = atlasMetadataCid;
|
|
598
|
+
objectLayerData.atlasSpriteSheetId = atlasDoc._id;
|
|
614
599
|
} catch (atlasError) {
|
|
615
|
-
logger.error(
|
|
600
|
+
logger.error(`Failed to generate atlas for "${itemId}":`, atlasError);
|
|
616
601
|
}
|
|
617
|
-
|
|
618
|
-
// Compute final SHA-256 (includes render CIDs)
|
|
619
|
-
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
620
|
-
|
|
621
|
-
// Pin data JSON to IPFS
|
|
622
|
-
if (ipfsClient) {
|
|
623
|
-
try {
|
|
624
|
-
const itemId = objectLayerData.data.item.id;
|
|
625
|
-
const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
|
|
626
|
-
const ipfsResult = await ipfsClient.addJsonToIpfs(objectLayerData.data, `${itemId}_data.json`, mfsPath);
|
|
627
|
-
if (ipfsResult) {
|
|
628
|
-
objectLayerData.cid = ipfsResult.cid;
|
|
629
|
-
if (createPinRecord) {
|
|
630
|
-
await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
} catch (ipfsError) {
|
|
634
|
-
logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
} else {
|
|
638
|
-
// No atlas generation - compute SHA-256 without render CIDs
|
|
639
|
-
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
640
602
|
}
|
|
641
603
|
|
|
642
|
-
|
|
643
|
-
const
|
|
644
|
-
|
|
604
|
+
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
605
|
+
const dataCid = await ObjectLayerEngine.pinObjectLayerData({ data: objectLayerData.data, itemId, options });
|
|
606
|
+
if (dataCid) objectLayerData.cid = dataCid;
|
|
645
607
|
|
|
646
608
|
const objectLayer = await (await ObjectLayer.upsertByItemId(objectLayerData)).populate('objectLayerRenderFramesId');
|
|
647
609
|
|
|
648
610
|
if (oldRenderFramesId && !oldRenderFramesId.equals(objectLayerRenderFramesDoc._id)) {
|
|
649
611
|
await ObjectLayerRenderFrames.findByIdAndDelete(oldRenderFramesId);
|
|
650
612
|
}
|
|
651
|
-
logger.info(`ObjectLayer for item "${
|
|
613
|
+
logger.info(`ObjectLayer for item "${itemId}" persisted with id: ${objectLayer._id}`);
|
|
652
614
|
|
|
653
615
|
return { objectLayer, objectLayerRenderFramesDoc };
|
|
654
616
|
}
|
|
655
617
|
|
|
656
618
|
/**
|
|
657
|
-
*
|
|
658
|
-
* with cut-over consistency: a new ObjectLayerRenderFrames is created, then atlas and all
|
|
659
|
-
* CIDs are staged BEFORE the live ObjectLayer is touched. The live document is updated
|
|
660
|
-
* atomically via findByIdAndUpdate only after all CIDs are computed.
|
|
619
|
+
* Pins the object layer data JSON to IPFS and records the pin.
|
|
661
620
|
*
|
|
662
621
|
* @static
|
|
663
622
|
* @param {Object} params - Parameters.
|
|
664
|
-
* @param {
|
|
665
|
-
* @param {
|
|
666
|
-
* @param {Object} params.
|
|
667
|
-
* @
|
|
668
|
-
* @param {Object} params.objectLayerData - Object layer payload (must include `data`).
|
|
669
|
-
* @param {CreateDocumentsOptions} [params.updateOptions={}] - Additional options controlling atlas generation and IPFS pinning.
|
|
670
|
-
* @returns {Promise<CreateDocumentsResult>} The persisted documents.
|
|
623
|
+
* @param {Object} params.data - The `data` sub-document to pin.
|
|
624
|
+
* @param {string} params.itemId - Object layer item id.
|
|
625
|
+
* @param {Object} [params.options] - Router options ({ host, path }).
|
|
626
|
+
* @returns {Promise<string>} The CID, or an empty string when IPFS is unreachable.
|
|
671
627
|
* @memberof CyberiaObjectLayer
|
|
672
628
|
*/
|
|
673
|
-
static async
|
|
674
|
-
|
|
675
|
-
ObjectLayer,
|
|
676
|
-
ObjectLayerRenderFrames,
|
|
677
|
-
objectLayerRenderFramesData,
|
|
678
|
-
objectLayerData,
|
|
679
|
-
updateOptions = {},
|
|
680
|
-
}) {
|
|
681
|
-
const { generateAtlas = true, atlasServiceContext = null } = updateOptions;
|
|
682
|
-
|
|
683
|
-
// 1. Load existing ObjectLayer to get old references
|
|
684
|
-
const existingObjectLayer = await ObjectLayer.findById(objectLayerId);
|
|
685
|
-
if (!existingObjectLayer) {
|
|
686
|
-
throw new Error('ObjectLayer not found for update');
|
|
687
|
-
}
|
|
688
|
-
const oldRenderFramesId = existingObjectLayer.objectLayerRenderFramesId;
|
|
689
|
-
|
|
690
|
-
// 2. Create NEW RenderFrames (avoid mutating old doc mid-update)
|
|
691
|
-
const objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.create(objectLayerRenderFramesData);
|
|
692
|
-
objectLayerData.objectLayerRenderFramesId = objectLayerRenderFramesDoc._id;
|
|
693
|
-
|
|
694
|
-
// 3. Set up render CIDs
|
|
695
|
-
if (!objectLayerData.data.render) objectLayerData.data.render = {};
|
|
696
|
-
objectLayerData.data.render.cid = '';
|
|
697
|
-
objectLayerData.data.render.metadataCid = '';
|
|
698
|
-
|
|
699
|
-
// 4. Stage atlas + IPFS CIDs BEFORE updating the ObjectLayer
|
|
700
|
-
if (generateAtlas && atlasServiceContext) {
|
|
701
|
-
const {
|
|
702
|
-
req,
|
|
703
|
-
res,
|
|
704
|
-
options,
|
|
705
|
-
AtlasSpriteSheetService,
|
|
706
|
-
IpfsClient: ipfsClient,
|
|
707
|
-
createPinRecord,
|
|
708
|
-
} = atlasServiceContext;
|
|
709
|
-
|
|
710
|
-
try {
|
|
711
|
-
const stagingOL = {
|
|
712
|
-
data: objectLayerData.data,
|
|
713
|
-
objectLayerRenderFramesId: objectLayerRenderFramesDoc,
|
|
714
|
-
};
|
|
715
|
-
const result = await AtlasSpriteSheetService.generate(
|
|
716
|
-
{ objectLayer: stagingOL, auth: req ? req.auth : undefined },
|
|
717
|
-
res,
|
|
718
|
-
options,
|
|
719
|
-
{ skipObjectLayerSave: true },
|
|
720
|
-
);
|
|
721
|
-
objectLayerData.data.render.cid = result.atlasCid;
|
|
722
|
-
objectLayerData.data.render.metadataCid = result.atlasMetadataCid;
|
|
723
|
-
objectLayerData.atlasSpriteSheetId = result.atlasDoc._id;
|
|
724
|
-
} catch (atlasError) {
|
|
725
|
-
logger.error('Failed to generate atlas during update staging:', atlasError);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
// Compute final SHA-256 (includes render CIDs)
|
|
729
|
-
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
730
|
-
|
|
731
|
-
// Pin data JSON to IPFS
|
|
732
|
-
if (ipfsClient) {
|
|
733
|
-
try {
|
|
734
|
-
const itemId = objectLayerData.data.item.id;
|
|
735
|
-
const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
|
|
736
|
-
const ipfsResult = await ipfsClient.addJsonToIpfs(objectLayerData.data, `${itemId}_data.json`, mfsPath);
|
|
737
|
-
if (ipfsResult) {
|
|
738
|
-
objectLayerData.cid = ipfsResult.cid;
|
|
739
|
-
if (createPinRecord) {
|
|
740
|
-
await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
} catch (ipfsError) {
|
|
744
|
-
logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
} else {
|
|
748
|
-
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
// 5. Atomic update - ObjectLayer is fully populated with all CIDs
|
|
752
|
-
let objectLayer;
|
|
629
|
+
static async pinObjectLayerData({ data, itemId, options }) {
|
|
630
|
+
const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
|
|
753
631
|
try {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
} catch (error) {
|
|
762
|
-
logger.error('Error updating ObjectLayer:', error);
|
|
763
|
-
throw error;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
// 6. Clean up old RenderFrames
|
|
767
|
-
if (oldRenderFramesId && !oldRenderFramesId.equals(objectLayerRenderFramesDoc._id)) {
|
|
768
|
-
await ObjectLayerRenderFrames.findByIdAndDelete(oldRenderFramesId);
|
|
632
|
+
const ipfsResult = await IpfsClient.addJsonToIpfs(data, `${itemId}_data.json`, mfsPath);
|
|
633
|
+
if (!ipfsResult) return '';
|
|
634
|
+
await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
|
|
635
|
+
return ipfsResult.cid;
|
|
636
|
+
} catch (ipfsError) {
|
|
637
|
+
logger.warn(`Failed to pin data JSON for "${itemId}": ${ipfsError.message}`);
|
|
638
|
+
return '';
|
|
769
639
|
}
|
|
770
|
-
|
|
771
|
-
return { objectLayer, objectLayerRenderFramesDoc };
|
|
772
640
|
}
|
|
773
641
|
|
|
774
642
|
/**
|
|
@@ -780,32 +648,19 @@ export class ObjectLayerEngine {
|
|
|
780
648
|
* @static
|
|
781
649
|
* @param {Object} params - Parameters.
|
|
782
650
|
* @param {Object} params.objectLayer - The mongoose ObjectLayer document (must be populated).
|
|
783
|
-
* @param {Object} [params.
|
|
784
|
-
* @param {function} [params.createPinRecord=null] - The `createPinRecord` helper; when `null`, pin records are skipped.
|
|
785
|
-
* @param {Object} [params.options] - Server options (host, path) forwarded to `createPinRecord`.
|
|
651
|
+
* @param {Object} [params.options] - Router options ({ host, path }) forwarded to the pin record.
|
|
786
652
|
* @returns {Promise<Object>} The saved ObjectLayer document.
|
|
787
653
|
* @memberof CyberiaObjectLayer
|
|
788
654
|
*/
|
|
789
|
-
static async computeAndSaveFinalSha256({ objectLayer,
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
const ipfsResult = await ipfsClient.addJsonToIpfs(objectLayer.data, `${itemId}_data.json`, mfsPath);
|
|
797
|
-
if (ipfsResult) {
|
|
798
|
-
objectLayer.cid = ipfsResult.cid;
|
|
799
|
-
if (createPinRecord) {
|
|
800
|
-
await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
} catch (ipfsError) {
|
|
804
|
-
logger.warn('Failed to add object layer data to IPFS:', ipfsError.message);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
655
|
+
static async computeAndSaveFinalSha256({ objectLayer, options }) {
|
|
656
|
+
const cid = await ObjectLayerEngine.pinObjectLayerData({
|
|
657
|
+
data: objectLayer.data,
|
|
658
|
+
itemId: objectLayer.data.item.id,
|
|
659
|
+
options,
|
|
660
|
+
});
|
|
661
|
+
if (cid) objectLayer.cid = cid;
|
|
807
662
|
|
|
808
|
-
objectLayer.sha256 =
|
|
663
|
+
objectLayer.sha256 = ObjectLayerEngine.computeSha256(objectLayer.data);
|
|
809
664
|
objectLayer.markModified('data');
|
|
810
665
|
await objectLayer.save();
|
|
811
666
|
|
|
@@ -822,8 +677,7 @@ export class ObjectLayerEngine {
|
|
|
822
677
|
*
|
|
823
678
|
* Resolution order:
|
|
824
679
|
* 1. If the ObjectLayer document already has a `.cid` field, use it.
|
|
825
|
-
* 2. Otherwise
|
|
826
|
-
* data to IPFS as a side-effect) and persist it back to the document.
|
|
680
|
+
* 2. Otherwise pin the data to IPFS and persist the CID back to the document.
|
|
827
681
|
* 3. If IPFS is unreachable, fall back to a local SHA-256 so the caller at
|
|
828
682
|
* least gets a content hash (prefixed with `sha256:` to distinguish it
|
|
829
683
|
* from a real IPFS CID).
|
|
@@ -832,12 +686,11 @@ export class ObjectLayerEngine {
|
|
|
832
686
|
* @param {Object} params
|
|
833
687
|
* @param {string} params.itemId – human-readable item identifier.
|
|
834
688
|
* @param {import('mongoose').Model} params.ObjectLayer – Mongoose ObjectLayer model.
|
|
835
|
-
* @param {Object} [params.ipfsClient=null] – The IpfsClient module; when `null`, IPFS pinning is skipped and only SHA-256 fallback is returned.
|
|
836
689
|
* @param {Object} [params.options] – `{ host, path }` forwarded to pin helpers.
|
|
837
690
|
* @returns {Promise<{ cid: string, sha256: string, source: string }>}
|
|
838
691
|
* @memberof CyberiaObjectLayer
|
|
839
692
|
*/
|
|
840
|
-
static async resolveCanonicalCid({ itemId, ObjectLayer,
|
|
693
|
+
static async resolveCanonicalCid({ itemId, ObjectLayer, options }) {
|
|
841
694
|
const objectLayer = await ObjectLayer.findByItemId(itemId);
|
|
842
695
|
if (!objectLayer) {
|
|
843
696
|
throw new Error(`ObjectLayer "${itemId}" not found in database`);
|
|
@@ -850,25 +703,15 @@ export class ObjectLayerEngine {
|
|
|
850
703
|
return { cid: objectLayer.cid, sha256, source: 'db' };
|
|
851
704
|
}
|
|
852
705
|
|
|
853
|
-
// 2.
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
objectLayer.cid = ipfsResult.cid;
|
|
863
|
-
objectLayer.sha256 = sha256;
|
|
864
|
-
objectLayer.markModified('data');
|
|
865
|
-
await objectLayer.save();
|
|
866
|
-
logger.info(`Canonical CID computed and persisted for "${itemId}": ${ipfsResult.cid}`);
|
|
867
|
-
return { cid: ipfsResult.cid, sha256, source: 'ipfs' };
|
|
868
|
-
}
|
|
869
|
-
} catch (err) {
|
|
870
|
-
logger.warn(`IPFS unreachable while resolving canonical CID for "${itemId}": ${err.message}`);
|
|
871
|
-
}
|
|
706
|
+
// 2. Compute and persist via IPFS
|
|
707
|
+
const cid = await ObjectLayerEngine.pinObjectLayerData({ data: objectLayer.data, itemId, options });
|
|
708
|
+
if (cid) {
|
|
709
|
+
objectLayer.cid = cid;
|
|
710
|
+
objectLayer.sha256 = sha256;
|
|
711
|
+
objectLayer.markModified('data');
|
|
712
|
+
await objectLayer.save();
|
|
713
|
+
logger.info(`Canonical CID computed and persisted for "${itemId}": ${cid}`);
|
|
714
|
+
return { cid, sha256, source: 'ipfs' };
|
|
872
715
|
}
|
|
873
716
|
|
|
874
717
|
// 3. Fallback – return a sha256:-prefixed content hash
|
|
@@ -877,10 +720,63 @@ export class ObjectLayerEngine {
|
|
|
877
720
|
);
|
|
878
721
|
return { cid: `sha256:${sha256}`, sha256, source: 'sha256-fallback' };
|
|
879
722
|
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Tells whether an `ol` invocation asks for the atlas rebuild.
|
|
726
|
+
*
|
|
727
|
+
* `--to-atlas-sprite-sheet` always asks for it. `--upscale` names the
|
|
728
|
+
* human-resolution render and nothing else, so on its own it asks for the same
|
|
729
|
+
* rebuild; next to another action it only sets that action's pixel factor.
|
|
730
|
+
*
|
|
731
|
+
* @static
|
|
732
|
+
* @param {Object} [options={}] - Parsed `ol` command options.
|
|
733
|
+
* @returns {boolean} True when both atlas renders have to be rebuilt.
|
|
734
|
+
* @memberof CyberiaObjectLayer
|
|
735
|
+
*/
|
|
736
|
+
static selectAtlasRebuild(options = {}) {
|
|
737
|
+
const namedAnAction = Boolean(
|
|
738
|
+
options.import ||
|
|
739
|
+
options.minify ||
|
|
740
|
+
options.importTypes ||
|
|
741
|
+
options.drop ||
|
|
742
|
+
options.generate ||
|
|
743
|
+
options.showAtlasSpriteSheet ||
|
|
744
|
+
options.showFrame !== undefined,
|
|
745
|
+
);
|
|
746
|
+
return options.toAtlasSpriteSheet !== undefined || (options.upscale !== undefined && !namedAnAction);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Selects the item ids an `ol` action works on, such as `--minify` or
|
|
751
|
+
* `--to-atlas-sprite-sheet`.
|
|
752
|
+
*
|
|
753
|
+
* With no requested ids, every stored item id is taken. With requested ids,
|
|
754
|
+
* only the ids the collection holds are kept, so an action stays limited to
|
|
755
|
+
* documents that already exist.
|
|
756
|
+
*
|
|
757
|
+
* @static
|
|
758
|
+
* @param {Object} params
|
|
759
|
+
* @param {string[]} params.storedItemIds - Item ids of the ObjectLayer collection, or of one instance.
|
|
760
|
+
* @param {string[]} [params.requestedItemIds=[]] - Item ids given on the command line.
|
|
761
|
+
* @returns {{ itemIds: string[], missingItemIds: string[] }}
|
|
762
|
+
* @memberof CyberiaObjectLayer
|
|
763
|
+
*/
|
|
764
|
+
static selectStoredItemIds({ storedItemIds, requestedItemIds = [] }) {
|
|
765
|
+
const normalize = (ids) =>
|
|
766
|
+
[...new Set((ids ?? []).filter((id) => typeof id === 'string').map((id) => id.trim()))].filter(Boolean);
|
|
767
|
+
const stored = normalize(storedItemIds);
|
|
768
|
+
const requested = normalize(requestedItemIds);
|
|
769
|
+
if (requested.length === 0) return { itemIds: stored, missingItemIds: [] };
|
|
770
|
+
const storedSet = new Set(stored);
|
|
771
|
+
return {
|
|
772
|
+
itemIds: requested.filter((id) => storedSet.has(id)),
|
|
773
|
+
missingItemIds: requested.filter((id) => !storedSet.has(id)),
|
|
774
|
+
};
|
|
775
|
+
}
|
|
880
776
|
}
|
|
881
777
|
|
|
882
778
|
// ──────────────────────────────────────────────────────────────────────────
|
|
883
|
-
//
|
|
779
|
+
// Named exports of the ObjectLayerEngine statics the Cyberia CLI imports.
|
|
884
780
|
// ──────────────────────────────────────────────────────────────────────────
|
|
885
781
|
|
|
886
782
|
/**
|
|
@@ -890,27 +786,6 @@ export class ObjectLayerEngine {
|
|
|
890
786
|
*/
|
|
891
787
|
export const pngDirectoryIteratorByObjectLayerType = ObjectLayerEngine.pngDirectoryIteratorByObjectLayerType;
|
|
892
788
|
|
|
893
|
-
/**
|
|
894
|
-
* @see {@link ObjectLayerEngine.readPngAsync}
|
|
895
|
-
* @function readPngAsync
|
|
896
|
-
* @memberof CyberiaObjectLayer
|
|
897
|
-
*/
|
|
898
|
-
export const readPngAsync = ObjectLayerEngine.readPngAsync;
|
|
899
|
-
|
|
900
|
-
/**
|
|
901
|
-
* @see {@link ObjectLayerEngine.frameFactory}
|
|
902
|
-
* @function frameFactory
|
|
903
|
-
* @memberof CyberiaObjectLayer
|
|
904
|
-
*/
|
|
905
|
-
export const frameFactory = ObjectLayerEngine.frameFactory;
|
|
906
|
-
|
|
907
|
-
/**
|
|
908
|
-
* @see {@link ObjectLayerEngine.processAndPushFrame}
|
|
909
|
-
* @function processAndPushFrame
|
|
910
|
-
* @memberof CyberiaObjectLayer
|
|
911
|
-
*/
|
|
912
|
-
export const processAndPushFrame = ObjectLayerEngine.processAndPushFrame;
|
|
913
|
-
|
|
914
789
|
/**
|
|
915
790
|
* @see {@link ObjectLayerEngine.buildImgFromTile}
|
|
916
791
|
* @function buildImgFromTile
|
|
@@ -918,48 +793,6 @@ export const processAndPushFrame = ObjectLayerEngine.processAndPushFrame;
|
|
|
918
793
|
*/
|
|
919
794
|
export const buildImgFromTile = ObjectLayerEngine.buildImgFromTile;
|
|
920
795
|
|
|
921
|
-
/**
|
|
922
|
-
* @see {@link ObjectLayerEngine.buildObjectLayerDataFromDirectory}
|
|
923
|
-
* @function buildObjectLayerDataFromDirectory
|
|
924
|
-
* @memberof CyberiaObjectLayer
|
|
925
|
-
*/
|
|
926
|
-
export const buildObjectLayerDataFromDirectory = ObjectLayerEngine.buildObjectLayerDataFromDirectory;
|
|
927
|
-
|
|
928
|
-
/**
|
|
929
|
-
* @see {@link ObjectLayerEngine.computeSha256}
|
|
930
|
-
* @function computeSha256
|
|
931
|
-
* @memberof CyberiaObjectLayer
|
|
932
|
-
*/
|
|
933
|
-
export const computeSha256 = ObjectLayerEngine.computeSha256;
|
|
934
|
-
|
|
935
|
-
/**
|
|
936
|
-
* @see {@link ObjectLayerEngine.createObjectLayerDocuments}
|
|
937
|
-
* @function createObjectLayerDocuments
|
|
938
|
-
* @memberof CyberiaObjectLayer
|
|
939
|
-
*/
|
|
940
|
-
export const createObjectLayerDocuments = ObjectLayerEngine.createObjectLayerDocuments;
|
|
941
|
-
|
|
942
|
-
/**
|
|
943
|
-
* @see {@link ObjectLayerEngine.updateObjectLayerDocuments}
|
|
944
|
-
* @function updateObjectLayerDocuments
|
|
945
|
-
* @memberof CyberiaObjectLayer
|
|
946
|
-
*/
|
|
947
|
-
export const updateObjectLayerDocuments = ObjectLayerEngine.updateObjectLayerDocuments;
|
|
948
|
-
|
|
949
|
-
/**
|
|
950
|
-
* @see {@link ObjectLayerEngine.computeAndSaveFinalSha256}
|
|
951
|
-
* @function computeAndSaveFinalSha256
|
|
952
|
-
* @memberof CyberiaObjectLayer
|
|
953
|
-
*/
|
|
954
|
-
export const computeAndSaveFinalSha256 = ObjectLayerEngine.computeAndSaveFinalSha256;
|
|
955
|
-
|
|
956
|
-
/**
|
|
957
|
-
* @see {@link ObjectLayerEngine.writeStaticFrameAssets}
|
|
958
|
-
* @function writeStaticFrameAssets
|
|
959
|
-
* @memberof CyberiaObjectLayer
|
|
960
|
-
*/
|
|
961
|
-
export const writeStaticFrameAssets = ObjectLayerEngine.writeStaticFrameAssets;
|
|
962
|
-
|
|
963
796
|
/**
|
|
964
797
|
* @see {@link ObjectLayerEngine.resolveCanonicalCid}
|
|
965
798
|
* @function resolveCanonicalCid
|