@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.
Files changed (269) hide show
  1. package/.env.example +17 -5
  2. package/.github/workflows/coverall.cyberia.ci.yml +10 -0
  3. package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
  4. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
  5. package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
  6. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
  7. package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
  8. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
  9. package/.github/workflows/engine-cyberia.ci.yml +1 -1
  10. package/.github/workflows/publish.cyberia.ci.yml +44 -0
  11. package/AGENTS.md +61 -12
  12. package/CHANGELOG.md +159 -161
  13. package/CLI-HELP.md +20 -13
  14. package/Dockerfile +1 -1
  15. package/Dockerfile.dev +1 -1
  16. package/Dockerfile.test +2 -2
  17. package/README.md +28 -28
  18. package/bin/build.js +96 -21
  19. package/bin/cyberia.js +1247 -1373
  20. package/bin/index.js +1247 -1373
  21. package/compose.env +17 -5
  22. package/conf.js +7 -4
  23. package/deploy/cyberia-client/deploy.sh +10 -11
  24. package/deploy/cyberia-client/package.sh +0 -1
  25. package/deploy/cyberia-client/state.sh +3 -2
  26. package/deploy/cyberia-server/deploy.sh +10 -11
  27. package/deploy/cyberia-server/package.sh +0 -1
  28. package/deploy/cyberia-server/state.sh +3 -2
  29. package/deploy/dd-cyberia/deploy.sh +5 -5
  30. package/deploy/dd-cyberia/init.sh +15 -14
  31. package/deploy/dd-cyberia/package.sh +0 -1
  32. package/deploy/dd-cyberia/state.sh +2 -2
  33. package/deploy/dd-cyberia/sync-deploy.sh +139 -75
  34. package/deploy/lib/config.sh +29 -0
  35. package/deploy/lib/github-actions-logging.sh +92 -76
  36. package/deploy/lib/host.sh +28 -19
  37. package/deploy/lib/state.sh +4 -1
  38. package/deploy/pwa-microservices-template/deploy.sh +10 -8
  39. package/deploy/release/deploy.sh +0 -2
  40. package/deployment.yaml +1 -1
  41. package/docker-compose.yml +23 -17
  42. package/docs/coverage/cyberia/api/cyberia-instance/cyberia-fallback-capture.js.html +1591 -0
  43. package/docs/coverage/cyberia/api/cyberia-instance/index.html +116 -0
  44. package/docs/coverage/cyberia/api/cyberia-server-defaults/cyberia-server-defaults.js.html +4138 -0
  45. package/docs/coverage/cyberia/api/cyberia-server-defaults/index.html +116 -0
  46. package/docs/coverage/cyberia/api/object-layer/index.html +116 -0
  47. package/docs/coverage/cyberia/api/object-layer/object-layer.model.js.html +1393 -0
  48. package/docs/coverage/cyberia/base.css +362 -0
  49. package/docs/coverage/cyberia/block-navigation.js +82 -0
  50. package/docs/coverage/cyberia/favicon.png +0 -0
  51. package/docs/coverage/cyberia/index.html +161 -0
  52. package/docs/coverage/cyberia/prettify.css +101 -0
  53. package/docs/coverage/cyberia/prettify.js +937 -0
  54. package/docs/coverage/cyberia/projects/cyberia/atlas-sprite-sheet-generator.js.html +1315 -0
  55. package/docs/coverage/cyberia/projects/cyberia/index.html +176 -0
  56. package/docs/coverage/cyberia/projects/cyberia/instance-backup.js.html +715 -0
  57. package/docs/coverage/cyberia/projects/cyberia/instance-data.js.html +2182 -0
  58. package/docs/coverage/cyberia/projects/cyberia/shape-generator.js.html +3265 -0
  59. package/docs/coverage/cyberia/projects/cyberia/stat-balance.js.html +328 -0
  60. package/docs/coverage/cyberia/sort-arrow-sprite.png +0 -0
  61. package/docs/coverage/cyberia/sorter.js +205 -0
  62. package/hardhat/package-lock.json +2 -2
  63. package/hardhat/package.json +1 -1
  64. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  65. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +1 -1
  66. package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
  67. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  68. package/manifests/deployment/mongo-express/deployment.yaml +46 -27
  69. package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
  70. package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
  71. package/manifests/deployment/mongo-express/service.yaml +16 -0
  72. package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
  73. package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
  74. package/package.json +19 -17
  75. package/scripts/test-monitor.sh +3 -3
  76. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +14 -9
  77. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
  78. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  79. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +88 -184
  80. package/src/api/cyberia-action/cyberia-action.router.js +2 -2
  81. package/src/api/cyberia-action/cyberia-action.service.js +3 -4
  82. package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
  83. package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
  84. package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
  85. package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
  86. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -3
  87. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
  88. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +12 -34
  89. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +15 -32
  90. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
  91. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
  92. package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
  93. package/src/api/cyberia-entity/cyberia-entity.service.js +1 -1
  94. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
  95. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
  96. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +16 -1
  97. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +466 -3
  98. package/src/api/cyberia-instance/cyberia-fallback-capture.js +87 -51
  99. package/src/api/cyberia-instance/cyberia-fallback-world.js +21 -40
  100. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
  101. package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
  102. package/src/api/cyberia-instance/cyberia-instance-map.service.js +34 -141
  103. package/src/api/cyberia-instance/cyberia-instance.controller.js +1 -4
  104. package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
  105. package/src/api/cyberia-instance/cyberia-instance.router.js +3 -16
  106. package/src/api/cyberia-instance/cyberia-instance.service.js +3 -43
  107. package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
  108. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
  109. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +74 -1
  110. package/src/api/cyberia-map/cyberia-map.service.js +6 -2
  111. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
  112. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
  113. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
  114. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
  115. package/src/api/cyberia-quest/cyberia-quest.router.js +3 -3
  116. package/src/api/cyberia-quest/cyberia-quest.service.js +3 -3
  117. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
  118. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -188
  119. package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
  120. package/src/api/file/file.ref.js +153 -0
  121. package/src/api/file/file.ref.json +11 -2
  122. package/src/api/object-layer/object-layer.model.js +47 -12
  123. package/src/api/object-layer/object-layer.router.js +10 -3
  124. package/src/api/object-layer/object-layer.service.js +113 -120
  125. package/src/cli/app.js +12 -1
  126. package/src/cli/client.js +2 -2
  127. package/src/cli/cluster.js +80 -18
  128. package/src/cli/deploy.js +215 -34
  129. package/src/cli/docker-compose.js +1 -1
  130. package/src/cli/fs-selection.js +115 -0
  131. package/src/cli/fs.js +158 -342
  132. package/src/cli/index.js +22 -10
  133. package/src/cli/release.js +3 -1
  134. package/src/cli/repository.js +35 -9
  135. package/src/cli/run.js +80 -199
  136. package/src/cli/test.js +4 -0
  137. package/src/cli/wireguard.js +32 -31
  138. package/src/client/components/core/Badge.js +0 -1
  139. package/src/client/components/core/CssCore.js +8 -1
  140. package/src/client/components/core/Docs.js +77 -100
  141. package/src/client/components/core/Modal.js +77 -23
  142. package/src/client/components/core/ToolTip.js +15 -0
  143. package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +0 -2
  144. package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
  145. package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
  146. package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
  147. package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
  148. package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
  149. package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
  150. package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
  151. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
  152. package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
  153. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +0 -34
  154. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
  155. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
  156. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +0 -4
  157. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
  158. package/src/client/components/default/AppShellDefault.js +1 -4
  159. package/src/client/components/itemledger/AppShellItemledger.js +0 -2
  160. package/src/client/components/underpost/AppShellUnderpost.js +1 -1
  161. package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
  162. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +280 -24
  163. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
  164. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
  165. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
  166. package/src/client/public/cyberia-docs/CYBERIA.md +28 -28
  167. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
  168. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  169. package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
  170. package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
  171. package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
  172. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
  173. package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
  174. package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
  175. package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
  176. package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
  177. package/src/client/services/object-layer/object-layer.management.js +6 -10
  178. package/src/client/services/object-layer/object-layer.service.js +3 -1
  179. package/src/client/ssr/views/Cyberia404.js +3 -3
  180. package/src/client-builder/client-build-docs.js +52 -52
  181. package/src/client-builder/client-build.js +67 -44
  182. package/src/client-builder/client-bundle.js +347 -0
  183. package/src/db/mongo/MongoExpress.js +187 -0
  184. package/src/grpc/cyberia/grpc-server.js +5 -7
  185. package/src/index.js +1 -1
  186. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +143 -146
  187. package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
  188. package/src/projects/cyberia/besu-genesis-generator.js +5 -14
  189. package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
  190. package/src/projects/cyberia/catalog-cyberia.js +3 -2
  191. package/src/projects/cyberia/gemini-client.js +3 -3
  192. package/src/projects/cyberia/generate-saga.js +4 -11
  193. package/src/projects/cyberia/hot-reload-trigger.js +17 -28
  194. package/src/projects/cyberia/instance-backup.js +210 -0
  195. package/src/projects/cyberia/instance-data.js +177 -257
  196. package/src/projects/cyberia/map-preview-generator.js +32 -68
  197. package/src/projects/cyberia/object-layer.js +152 -319
  198. package/src/projects/cyberia/seed-audio.js +139 -0
  199. package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
  200. package/src/projects/cyberia/semantic-layer-generator.js +2 -18
  201. package/src/projects/cyberia/stat-balance.js +81 -0
  202. package/src/projects/cyberia/stat-commands.js +23 -0
  203. package/src/projects/cyberia/stat-contract-generator.js +101 -0
  204. package/src/runtime/cyberia-client/Dockerfile +8 -4
  205. package/src/runtime/cyberia-client/Dockerfile.dev +5 -2
  206. package/src/runtime/cyberia-server/Dockerfile +9 -2
  207. package/src/runtime/cyberia-server/Dockerfile.dev +8 -1
  208. package/src/runtime/engine-cyberia/Dockerfile +1 -1
  209. package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
  210. package/src/runtime/engine-cyberia/Dockerfile.test +2 -2
  211. package/src/runtime/engine-cyberia/compose.env +17 -5
  212. package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
  213. package/src/server/build/coverage.js +113 -42
  214. package/src/server/build/package.js +55 -12
  215. package/src/server/build/testing.js +59 -9
  216. package/src/server/network/middlewares.js +8 -2
  217. package/src/server/network/underpost-gateway.js +113 -14
  218. package/src/server/ops/logger.js +70 -35
  219. package/src/server/runtime/conf.js +40 -9
  220. package/src/server/runtime/start.js +11 -2
  221. package/src/server/storage/data-query.js +16 -0
  222. package/src/server/storage/downloader.js +62 -14
  223. package/src/server/storage/zip.js +153 -0
  224. package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
  225. package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
  226. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +34 -0
  227. package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
  228. package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
  229. package/test/integration/app/cyberia/cyberia-instance-conf-defaults.test.js +16 -22
  230. package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
  231. package/test/integration/app/cyberia/cyberia-load.test.js +6 -7
  232. package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
  233. package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
  234. package/test/integration/app/cyberia/fallback-world-capture.test.js +87 -2
  235. package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
  236. package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
  237. package/test/integration/app/cyberia/seed-audio.test.js +275 -0
  238. package/test/integration/infra/2-network/wireguard-cli.test.js +33 -9
  239. package/test/integration/infra/2-network/wireguard-edge.test.js +58 -18
  240. package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
  241. package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
  242. package/test/integration/infra/4-ingress/underpost-ingress.test.js +1 -1
  243. package/test/unit/catalog.test.js +13 -2
  244. package/test/unit/client-build-docs.test.js +97 -70
  245. package/test/unit/client-bundle.test.js +313 -0
  246. package/test/unit/conf-resolution.test.js +58 -7
  247. package/test/unit/coverage-artifact.test.js +120 -29
  248. package/test/unit/cyberia/instance-backup.test.js +183 -0
  249. package/test/unit/cyberia/instance-data.test.js +314 -0
  250. package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
  251. package/test/unit/cyberia/publish-workflow.test.js +22 -0
  252. package/test/unit/cyberia/stat-balance.test.js +69 -0
  253. package/test/unit/deploy-legacy-gateway-sweep.test.js +63 -0
  254. package/test/unit/deploy-log-table.test.js +76 -5
  255. package/test/unit/downloader-integrity.test.js +98 -0
  256. package/test/unit/file-reference-registry.test.js +141 -0
  257. package/test/unit/fs-storage-paths.test.js +596 -0
  258. package/test/unit/gateway-pod-fetch.test.js +95 -0
  259. package/test/unit/letsencrypt-issuer.test.js +101 -0
  260. package/test/unit/logger-redaction.test.js +29 -0
  261. package/test/unit/package.test.js +70 -16
  262. package/test/unit/prepare-host.test.js +84 -1
  263. package/test/unit/release-bump.test.js +3 -1
  264. package/test/unit/start-options.test.js +12 -0
  265. package/test/unit/test-tiers.test.js +27 -0
  266. package/test/unit/zip-archive.test.js +142 -0
  267. package/vitest.config.js +11 -3
  268. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
  269. 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} CreateDocumentsOptions
69
- * @property {boolean} [generateAtlas=true] - Whether to generate the atlas sprite sheet after creating documents.
70
- * @property {Object} [atlasServiceContext] - Context required by AtlasSpriteSheetService.generate (req, res, options).
71
- * @property {Object} [atlasServiceContext.req] - Express-like request object (must include auth).
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: metadata.objectLayerRenderFramesData.frame_duration || 250,
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
- // Build objectLayerData
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
- * Creates new ObjectLayerRenderFrames and ObjectLayer documents in MongoDB from the
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
- * If an existing ObjectLayer with the same `data.item.id` is found, it is atomically
559
- * replaced (findByIdAndUpdate) and the old ObjectLayerRenderFrames is cleaned up.
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 {CreateDocumentsOptions} [params.createOptions={}] - Additional options controlling atlas generation and IPFS pinning.
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 createObjectLayerDocuments({
567
+ static async persistObjectLayerDocuments({
572
568
  ObjectLayer,
573
569
  ObjectLayerRenderFrames,
574
570
  objectLayerRenderFramesData,
575
571
  objectLayerData,
576
- createOptions = {},
572
+ persistOptions = {},
577
573
  }) {
578
- const { generateAtlas = true, atlasServiceContext = null } = createOptions;
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
- // 1. Persist ObjectLayerRenderFrames (not queried by the viewer table)
581
- const objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.create(objectLayerRenderFramesData);
579
+ const existing = await ObjectLayer.findByItemId(itemId);
580
+ const oldRenderFramesId = existing?.objectLayerRenderFramesId;
582
581
 
583
- // 2. Set up references in memory
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
- // 3. Stage atlas + IPFS CIDs BEFORE creating/updating the ObjectLayer
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 stagingOL = {
602
- data: objectLayerData.data,
603
- objectLayerRenderFramesId: objectLayerRenderFramesDoc,
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
- { skipObjectLayerSave: true },
610
- );
611
- objectLayerData.data.render.cid = result.atlasCid;
612
- objectLayerData.data.render.metadataCid = result.atlasMetadataCid;
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('Failed to generate atlas during staging:', atlasError);
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
- // 4. Atomic create/upsert - ObjectLayer is fully populated with all CIDs
643
- const existingByItemId = await ObjectLayer.findByItemId(objectLayerData.data.item.id);
644
- const oldRenderFramesId = existingByItemId?.objectLayerRenderFramesId;
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 "${objectLayerData.data.item.id}" persisted with id: ${objectLayer._id}`);
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
- * Updates an existing ObjectLayer and its ObjectLayerRenderFrames from the provided data,
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 {string} params.objectLayerId - The `_id` of the ObjectLayer document to update.
665
- * @param {Object} params.ObjectLayer - Mongoose ObjectLayer model.
666
- * @param {Object} params.ObjectLayerRenderFrames - Mongoose ObjectLayerRenderFrames model.
667
- * @param {ObjectLayerRenderFramesData} params.objectLayerRenderFramesData - Render frames payload.
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 updateObjectLayerDocuments({
674
- objectLayerId,
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
- objectLayer = await ObjectLayer.findByIdAndUpdate(objectLayerId, objectLayerData, {
755
- returnDocument: 'after',
756
- }).populate('objectLayerRenderFramesId');
757
- if (!objectLayer) {
758
- throw new Error('ObjectLayer not found for update');
759
- }
760
- logger.info(`ObjectLayer updated atomically with id: ${objectLayerId}`);
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.ipfsClient=null] - The IpfsClient module; when `null`, IPFS pinning is skipped.
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, ipfsClient = null, createPinRecord = null, options }) {
790
- const finalSha256 = ObjectLayerEngine.computeSha256(objectLayer.data);
791
-
792
- if (ipfsClient) {
793
- try {
794
- const itemId = objectLayer.data.item.id;
795
- const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
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 = finalSha256;
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 compute it on-the-fly via `ipfsClient.addJsonToIpfs` (pins the
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, ipfsClient = null, options }) {
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. Try to compute and persist via IPFS
854
- if (ipfsClient) {
855
- try {
856
- const ipfsResult = await ipfsClient.addJsonToIpfs(
857
- objectLayer.data,
858
- `${itemId}_data.json`,
859
- `/object-layer/${itemId}/${itemId}_data.json`,
860
- );
861
- if (ipfsResult) {
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
- // Backward-compatible named exports matching the original destructured imports.
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