@operato/scene-ops 10.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/cjs/apply-model.js +328 -0
- package/dist/cjs/apply-model.js.map +1 -0
- package/dist/cjs/apply-scene.js +359 -0
- package/dist/cjs/apply-scene.js.map +1 -0
- package/dist/cjs/index.js +19 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/model.js +11 -0
- package/dist/cjs/model.js.map +1 -0
- package/dist/cjs/ops.js +3 -0
- package/dist/cjs/ops.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/src/apply-model.d.ts +47 -0
- package/dist/src/apply-model.js +321 -0
- package/dist/src/apply-model.js.map +1 -0
- package/dist/src/apply-scene.d.ts +94 -0
- package/dist/src/apply-scene.js +351 -0
- package/dist/src/apply-scene.js.map +1 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.js +16 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/model.d.ts +44 -0
- package/dist/src/model.js +10 -0
- package/dist/src/model.js.map +1 -0
- package/dist/src/ops.d.ts +135 -0
- package/dist/src/ops.js +2 -0
- package/dist/src/ops.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +50 -0
- package/src/apply-model.ts +370 -0
- package/src/apply-scene.ts +397 -0
- package/src/index.ts +15 -0
- package/src/model.ts +46 -0
- package/src/ops.ts +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.js","sourceRoot":"","sources":["../../src/ops.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Scene edit operations — the vocabulary for describing a change to a scene.\n *\n * One vocabulary, two appliers: `apply-model.ts` changes the stored JSON, `apply-scene.ts`\n * changes a Scene that is open on screen. They live together so they cannot drift.\n *\n * ── Targeting ──\n * Existing components are addressed by `refid` only. things-scene issues one to every\n * component; `model.id` is optional metadata and is absent more often than not, so it cannot\n * be a target. There is one channel, not two.\n *\n * ── The root ──\n * The scene root is the top-level parent (things-scene's model-layer) and carries its own\n * properties: fillStyle, width, height, fitMode, translate, scale, sky, skyColor, exposure,\n * the hemi/dir light fields, the camera fields. It has no refid, so `modifyScene` reaches it\n * and `modify` reaches everything else.\n *\n * Note that a board's *name* is a column on the board row in the database, not a field of\n * the scene model. Sending it through `modifyScene` writes a dead key into the JSON and\n * changes nothing on screen.\n */\nimport type { SceneComponentModel, SceneModel } from './model.js'\n\nexport type AlignDirection = 'left' | 'right' | 'center' | 'top' | 'middle' | 'bottom'\n\nexport type DistributeAxis = 'horizontal' | 'vertical'\n\nexport type ZorderDirection = 'front' | 'back' | 'forward' | 'backward'\n\n/**\n * The layout an `arrange` operation asks for.\n *\n * This sits above align/distribute so that \"in a 3x2 grid\", \"in one row\", \"in a column\"\n * is one operation rather than a list of coordinates.\n *\n * Only left/top change — width and height are kept. Changing size is a separate `modify`.\n *\n * Positions are computed by the scene applier, because they need each component's current\n * width and height. The model applier treats `arrange` as a no-op.\n */\nexport type ArrangeLayout =\n | { type: 'grid'; cols: number; gap?: number; anchor?: { left: number; top: number } }\n | {\n type: 'row'\n gap?: number\n anchor?: { left: number; top: number }\n align?: 'start' | 'center' | 'end'\n }\n | {\n type: 'column'\n gap?: number\n anchor?: { left: number; top: number }\n align?: 'start' | 'center' | 'end'\n }\n\n/** An operation that changes the scene. */\nexport type SceneEditOp =\n | { op: 'add'; component: SceneComponentModel }\n | { op: 'remove'; refid: number }\n | { op: 'modify'; refid: number; patch: Partial<SceneComponentModel> }\n | { op: 'modifyScene'; patch: Partial<SceneModel> }\n | { op: 'replace'; model: SceneModel }\n | { op: 'align'; refids: number[]; direction: AlignDirection }\n | { op: 'distribute'; refids: number[]; axis: DistributeAxis }\n | { op: 'group'; refids: number[] }\n | { op: 'ungroup'; refid: number }\n | { op: 'zorder'; refid: number; direction: ZorderDirection }\n | { op: 'arrange'; refids: number[]; layout: ArrangeLayout }\n\n/**\n * An operation that changes what the viewer sees but not what the scene is.\n *\n * Separate from `SceneEditOp` on purpose: these leave the model alone, so they do not enter\n * the undo history and do not make the document dirty. A host that mixes the two ends up\n * asking the user to save because the AI scrolled the view.\n */\nexport type SceneActionOp =\n | { action: 'selectComponents'; refids: number[] }\n | { action: 'centerToComponent'; refid: number; animated?: boolean }\n | { action: 'fitToView'; mode?: 'fit' | 'ratio' | 'width' | 'height' }\n | { action: 'setSceneMode'; mode: 'edit' | 'view' }\n /** Outline several components at once — the \"these are all the matches\" of a search. */\n | { action: 'highlightComponents'; refids: number[] }\n\n/** A batch of edit operations, with whatever the proposer wants to say about them. */\nexport interface SceneEditPatch {\n ops: SceneEditOp[]\n /** One or two sentences, for the person who has to approve it. */\n summary: string\n /** 0..1 */\n confidence: number\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/tslib/tslib.d.ts","../src/model.ts","../src/ops.ts","../src/apply-model.ts","../src/apply-scene.ts","../src/index.ts","../../../node_modules/@types/node/compatibility/disposable.d.ts","../../../node_modules/@types/node/compatibility/indexable.d.ts","../../../node_modules/@types/node/compatibility/iterators.d.ts","../../../node_modules/@types/node/compatibility/index.d.ts","../../../node_modules/@types/node/globals.typedarray.d.ts","../../../node_modules/@types/node/buffer.buffer.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../node_modules/@types/node/web-globals/domexception.d.ts","../../../node_modules/@types/node/web-globals/events.d.ts","../../../node_modules/buffer/index.d.ts","../../../node_modules/undici-types/header.d.ts","../../../node_modules/undici-types/readable.d.ts","../../../node_modules/undici-types/file.d.ts","../../../node_modules/undici-types/fetch.d.ts","../../../node_modules/undici-types/formdata.d.ts","../../../node_modules/undici-types/connector.d.ts","../../../node_modules/undici-types/client.d.ts","../../../node_modules/undici-types/errors.d.ts","../../../node_modules/undici-types/dispatcher.d.ts","../../../node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/undici-types/global-origin.d.ts","../../../node_modules/undici-types/pool-stats.d.ts","../../../node_modules/undici-types/pool.d.ts","../../../node_modules/undici-types/handlers.d.ts","../../../node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/undici-types/agent.d.ts","../../../node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/undici-types/mock-agent.d.ts","../../../node_modules/undici-types/mock-client.d.ts","../../../node_modules/undici-types/mock-pool.d.ts","../../../node_modules/undici-types/mock-errors.d.ts","../../../node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/undici-types/retry-handler.d.ts","../../../node_modules/undici-types/retry-agent.d.ts","../../../node_modules/undici-types/api.d.ts","../../../node_modules/undici-types/interceptors.d.ts","../../../node_modules/undici-types/util.d.ts","../../../node_modules/undici-types/cookies.d.ts","../../../node_modules/undici-types/patch.d.ts","../../../node_modules/undici-types/websocket.d.ts","../../../node_modules/undici-types/eventsource.d.ts","../../../node_modules/undici-types/filereader.d.ts","../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/undici-types/content-type.d.ts","../../../node_modules/undici-types/cache.d.ts","../../../node_modules/undici-types/index.d.ts","../../../node_modules/@types/node/web-globals/fetch.d.ts","../../../node_modules/@types/node/web-globals/navigator.d.ts","../../../node_modules/@types/node/web-globals/storage.d.ts","../../../node_modules/@types/node/web-globals/streams.d.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/inspector.generated.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/sea.d.ts","../../../node_modules/@types/node/sqlite.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/index.d.ts","../../../node_modules/@jest/expect-utils/build/index.d.ts","../../../node_modules/chalk/index.d.ts","../../../node_modules/@sinclair/typebox/typebox.d.ts","../../../node_modules/@jest/schemas/build/index.d.ts","../../../node_modules/pretty-format/build/index.d.ts","../../../node_modules/jest-diff/build/index.d.ts","../../../node_modules/jest-matcher-utils/build/index.d.ts","../../../node_modules/expect/build/index.d.ts","../../../node_modules/@types/jest/index.d.ts"],"fileIdsList":[[58,108,125,126],[58,108,125,126,161],[58,108,125,126,163,166],[58,105,106,108,125,126],[58,107,108,125,126],[108,125,126],[58,108,113,125,126,143],[58,108,109,114,119,125,126,128,140,151],[58,108,109,110,119,125,126,128],[53,54,55,58,108,125,126],[58,108,111,125,126,152],[58,108,112,113,120,125,126,129],[58,108,113,125,126,140,148],[58,108,114,116,119,125,126,128],[58,107,108,115,125,126],[58,108,116,117,125,126],[58,108,118,119,125,126],[58,107,108,119,125,126],[58,108,119,120,121,125,126,140,151],[58,108,119,120,121,125,126,135,140,143],[58,100,108,116,119,122,125,126,128,140,151],[58,108,119,120,122,123,125,126,128,140,148,151],[58,108,122,124,125,126,140,148,151],[56,57,58,59,60,61,62,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157],[58,108,119,125,126],[58,108,125,126,127,151],[58,108,116,119,125,126,128,140],[58,108,125,126,129],[58,108,125,126,130],[58,107,108,125,126,131],[58,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157],[58,108,125,126,133],[58,108,125,126,134],[58,108,119,125,126,135,136],[58,108,125,126,135,137,152,154],[58,108,120,125,126],[58,108,119,125,126,140,141,143],[58,108,125,126,142,143],[58,108,125,126,140,141],[58,108,125,126,143],[58,108,125,126,144],[58,105,108,125,126,140,145,151],[58,108,119,125,126,146,147],[58,108,125,126,146,147],[58,108,113,125,126,128,140,148],[58,108,125,126,149],[58,108,125,126,128,150],[58,108,122,125,126,134,151],[58,108,113,125,126,152],[58,108,125,126,140,153],[58,108,125,126,127,154],[58,108,125,126,155],[58,100,108,125,126],[58,100,108,119,121,125,126,131,140,143,151,153,154,156],[58,108,125,126,140,157],[58,108,125,126,159,165],[58,108,125,126,163],[58,108,125,126,160,164],[58,108,125,126,162],[58,72,76,108,125,126,151],[58,72,108,125,126,140,151],[58,67,108,125,126],[58,69,72,108,125,126,148,151],[58,108,125,126,128,148],[58,108,125,126,158],[58,67,108,125,126,158],[58,69,72,108,125,126,128,151],[58,64,65,68,71,108,119,125,126,140,151],[58,72,79,108,125,126],[58,64,70,108,125,126],[58,72,93,94,108,125,126],[58,68,72,108,125,126,143,151,158],[58,93,108,125,126,158],[58,66,67,108,125,126,158],[58,72,108,125,126],[58,66,67,68,69,70,71,72,73,74,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,108,125,126],[58,72,87,108,125,126],[58,72,79,80,108,125,126],[58,70,72,80,81,108,125,126],[58,71,108,125,126],[58,64,67,72,108,125,126],[58,72,76,80,81,108,125,126],[58,76,108,125,126],[58,70,72,75,108,125,126,151],[58,64,69,72,79,108,125,126],[58,108,125,126,140],[58,67,72,93,108,125,126,156,158],[47,48,49,58,108,125,126],[47,49,50,58,108,125,126],[47,48,49,50,51,58,108,125,126],[47,58,108,125,126],[47,48,58,108,125,126]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6a5253138c5432c68a1510c70fe78a644fe2e632111ba778e1978010d6edfec","impliedFormat":1},{"version":"2bff0eeeb7940e0ffa525dd3ed8a8f139e02b896a130a5ff9094bba7bb492ddd","signature":"411a3210bdc804b7a5fac9e8411bdf55a775a21974daa0ed15bff6bb9efe471b"},{"version":"c71a9cd939f621d4f184238f86126bf86e5fb4309b8c337548a98dc00607f7e9","signature":"b56dd87ffa39030b9094bcbf2d36dbfa5bb273b9d9b059b11c2793c204e9177f"},{"version":"a38e9da950955cfce7f801fff612888302ffe12804be0cd55ac6d8dce1ce3968","signature":"cc238e55e711f6994d9cf7775451e243edb79d1ce2c8254884775fe9450a473e"},{"version":"b1ae624b1550a46d4b8c45385df83d9445d883368b731bef2c8a19fdbfec3233","signature":"0feba10954d2edf22d2e7d4559ab145dae2fb17a1e507b6e75d66f598148a70d"},{"version":"4b54ceb00fe6b4e6f2612cb966e3648ac70b5bc238e87ab8c1c363609a74b429","signature":"8229d30586d3560e5a3c150a0a2988e6d9a9306e7bc0fe0b702c66d6b1d940db"},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"913be43dad2a40e500104700aa26cfb5c51a976114bedf19624de43fdae7474f","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"78dbea00e90d2df8ea3dbef0cc379d95b8be9b71cd6bde4c28728f306811803b","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e1e46d0a9837ee058c100501080c920fa98081ea3956af0374308ba6f22a33e","impliedFormat":1},{"version":"272ca407e0c9068bdc5152552d876e68037ceae3de62e529306403e973dec8e1","impliedFormat":1},{"version":"fa7834c715d5357e4540cee40ce96c3250ddb67a7b879a6b7fa0e86d6696f121","impliedFormat":1},{"version":"22dfb07a7ab15b66ac043829056fe70124844636ae719551812ac631ba04985b","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"0cb167c371eaa8c869f8a7656a7296f2e4fae43b4d8b803a680236b24794e5f9","impliedFormat":1},{"version":"0a839dba0287cc0481ad4beedd48a1c64acf1e212ae865d1315f7007ca215161","impliedFormat":1},{"version":"38dc4655376cd1a4bd6bb3763d92949233e33d38d3dd3cbea7bbf218175a38ef","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"208a6a0bfb227bdf8fb964799d0a206c75cf03ccd72e63bf5495c9331354c6d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"48a679952eefe4cb776d5a0e1ccba2d3eb53b57448bbb7abc1fcebcbd5440188","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2d14da6ecb49bf828d83948765ec2d3a579d476bbb9645e749610baa6ec880ca","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"0aef708fb4c7a6b915e8305cbfac40cd207b032dbaabe9a01889a5fff3254681","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"ad9bdafb4e7abf14cc53ce7970486a84c87831e62891e5dfe798ddcd55e84701","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"71d3ae6a5e73ca4130762560425e00984ebaff64d5353a3333d1bb7eb86ef336","impliedFormat":1},{"version":"cdcc132f207d097d7d3aa75615ab9a2e71d6a478162dde8b67f88ea19f3e54de","impliedFormat":1},{"version":"0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","impliedFormat":1},{"version":"e1028394c1cf96d5d057ecc647e31e457b919092f882ed0c7092152b077fed9d","impliedFormat":1},{"version":"f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","impliedFormat":1},{"version":"5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","impliedFormat":1},{"version":"3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","impliedFormat":1},{"version":"ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","impliedFormat":1},{"version":"d96cc6598148bf1a98fb2e8dcf01c63a4b3558bdaec6ef35e087fd0562eb40ec","impliedFormat":1},{"version":"f8db4fea512ab759b2223b90ecbbe7dae919c02f8ce95ec03f7fb1cf757cfbeb","affectsGlobalScope":true,"impliedFormat":1}],"root":[[48,52]],"options":{"allowSyntheticDefaultImports":true,"declaration":true,"esModuleInterop":true,"experimentalDecorators":true,"importHelpers":true,"inlineSources":true,"module":99,"noEmitOnError":true,"outDir":"./","rootDir":"..","skipLibCheck":true,"sourceMap":true,"strict":true,"target":99,"useDefineForClassFields":true},"referencedMap":[[159,1],[162,2],[161,1],[167,3],[105,4],[106,4],[107,5],[58,6],[108,7],[109,8],[110,9],[53,1],[56,10],[54,1],[55,1],[111,11],[112,12],[113,13],[114,14],[115,15],[116,16],[117,16],[118,17],[119,18],[120,19],[121,20],[59,1],[57,1],[122,21],[123,22],[124,23],[158,24],[125,25],[126,1],[127,26],[128,27],[129,28],[130,29],[131,30],[132,31],[133,32],[134,33],[135,34],[136,34],[137,35],[138,1],[139,36],[140,37],[142,38],[141,39],[143,40],[144,41],[145,42],[146,43],[147,44],[148,45],[149,46],[150,47],[151,48],[152,49],[153,50],[154,51],[155,52],[60,1],[61,1],[62,1],[101,53],[102,1],[103,1],[104,40],[156,54],[157,55],[63,1],[160,1],[166,56],[164,57],[165,58],[163,59],[47,1],[45,1],[46,1],[8,1],[10,1],[9,1],[2,1],[11,1],[12,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[3,1],[19,1],[20,1],[4,1],[21,1],[25,1],[22,1],[23,1],[24,1],[26,1],[27,1],[28,1],[5,1],[29,1],[30,1],[31,1],[32,1],[6,1],[36,1],[33,1],[34,1],[35,1],[37,1],[7,1],[38,1],[43,1],[44,1],[39,1],[40,1],[41,1],[42,1],[1,1],[79,60],[89,61],[78,60],[99,62],[70,63],[69,64],[98,65],[92,66],[97,67],[72,68],[86,69],[71,70],[95,71],[67,72],[66,65],[96,73],[68,74],[73,75],[74,1],[77,75],[64,1],[100,76],[90,77],[81,78],[82,79],[84,80],[80,81],[83,82],[93,65],[75,83],[76,84],[85,85],[65,86],[88,77],[87,75],[91,1],[94,87],[50,88],[51,89],[52,90],[48,91],[49,92]],"version":"5.9.3"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@operato/scene-ops",
|
|
3
|
+
"version": "10.14.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/cjs/index.js",
|
|
6
|
+
"module": "./dist/src/index.js",
|
|
7
|
+
"author": "heartyoh",
|
|
8
|
+
"description": "Scene edit operations — a vocabulary for describing a change to a things-scene model, and the two appliers that carry it out (stored JSON model, live Scene)",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public",
|
|
12
|
+
"@operato:registry": "https://registry.npmjs.org"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/hatiolab/operato.git",
|
|
17
|
+
"directory": "packages/scene-ops"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "jest",
|
|
21
|
+
"lint": "eslint --ext .ts . --ignore-path .gitignore",
|
|
22
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json', JSON.stringify({type:'commonjs'})+'\\n')\"",
|
|
23
|
+
"clean": "rimraf './dist'"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@hatiolab/prettier-config": "^1.0.0",
|
|
27
|
+
"@types/jest": "^29.2.1",
|
|
28
|
+
"jest": "^29.2.1",
|
|
29
|
+
"rimraf": "^5.0.0",
|
|
30
|
+
"ts-jest": "^29.0.3",
|
|
31
|
+
"tslib": "^2.3.1",
|
|
32
|
+
"typescript": "^5.0.4"
|
|
33
|
+
},
|
|
34
|
+
"prettier": "@hatiolab/prettier-config",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"src",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"types": "./dist/src/index.d.ts",
|
|
41
|
+
"exports": {
|
|
42
|
+
".": {
|
|
43
|
+
"types": "./dist/src/index.d.ts",
|
|
44
|
+
"import": "./dist/src/index.js",
|
|
45
|
+
"require": "./dist/cjs/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./package.json": "./package.json"
|
|
48
|
+
},
|
|
49
|
+
"gitHead": "9988320c6a345eaa0b9623d6e641fee0650b6dbc"
|
|
50
|
+
}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applying edit operations to a stored scene model.
|
|
3
|
+
*
|
|
4
|
+
* Pure: nothing here mutates its input. This is the applier for a scene that is not open —
|
|
5
|
+
* a file being transformed, a template being instantiated, a proposal being previewed. For a
|
|
6
|
+
* scene that is open on screen, use `apply-scene.ts`; things-scene's own API is the authority
|
|
7
|
+
* there and several operations are deliberately no-ops here.
|
|
8
|
+
*/
|
|
9
|
+
import type { SceneComponentModel, SceneModel } from './model.js'
|
|
10
|
+
import type { SceneEditOp, SceneEditPatch } from './ops.js'
|
|
11
|
+
|
|
12
|
+
const EMPTY_SCENE: SceneModel = {
|
|
13
|
+
width: 1000,
|
|
14
|
+
height: 600,
|
|
15
|
+
components: []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PatchApplyReport {
|
|
19
|
+
/** The scene after the patch. Unchanged input is returned as-is when every op was a no-op. */
|
|
20
|
+
model: SceneModel
|
|
21
|
+
/** The ops that actually changed something. */
|
|
22
|
+
applied: SceneEditOp[]
|
|
23
|
+
/** The ops that did nothing — a refid that is not there, most often. */
|
|
24
|
+
missed: SceneEditOp[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function applyScenePatch(model: SceneModel | undefined, patch: SceneEditPatch): SceneModel {
|
|
28
|
+
return applyScenePatchVerbose(model, patch).model
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The same, but reporting which ops landed.
|
|
33
|
+
*
|
|
34
|
+
* `modify` and `remove` do nothing at all when the refid is not in the scene. Without this
|
|
35
|
+
* report the host answers "done" to a change that never happened — which is exactly what a
|
|
36
|
+
* language model producing a wrong refid looks like from the user's seat.
|
|
37
|
+
*/
|
|
38
|
+
export function applyScenePatchVerbose(
|
|
39
|
+
model: SceneModel | undefined,
|
|
40
|
+
patch: SceneEditPatch
|
|
41
|
+
): PatchApplyReport {
|
|
42
|
+
let result: SceneModel = model ?? EMPTY_SCENE
|
|
43
|
+
const applied: SceneEditOp[] = []
|
|
44
|
+
const missed: SceneEditOp[] = []
|
|
45
|
+
|
|
46
|
+
for (const op of patch.ops) {
|
|
47
|
+
if (SCENE_ONLY_OPS.has(op.op)) {
|
|
48
|
+
/* A no-op here, but the scene applier really does carry it out — count it as applied. */
|
|
49
|
+
applied.push(op)
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
const next = applyOp(result, op)
|
|
53
|
+
/*
|
|
54
|
+
* `componentsUnchanged` looks at the component list and at width/height/fillStyle only.
|
|
55
|
+
* It is here to catch a `modify`/`remove` that silently hit nothing, so it must not run
|
|
56
|
+
* for `modifyScene`, which legitimately changes other root keys such as `sky`.
|
|
57
|
+
*/
|
|
58
|
+
const componentMutating = op.op === 'modify' || op.op === 'remove'
|
|
59
|
+
if (next === result || (componentMutating && componentsUnchanged(result, next))) {
|
|
60
|
+
missed.push(op)
|
|
61
|
+
} else {
|
|
62
|
+
applied.push(op)
|
|
63
|
+
result = next
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { model: result, applied, missed }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function componentsUnchanged(prev: SceneModel, next: SceneModel): boolean {
|
|
71
|
+
/*
|
|
72
|
+
* `applyOp` always builds a new object, so comparing references tells us nothing and we
|
|
73
|
+
* compare contents. The component arrays come out of map/filter, so we compare element by
|
|
74
|
+
* element rather than by array identity.
|
|
75
|
+
*/
|
|
76
|
+
const a = prev.components ?? []
|
|
77
|
+
const b = next.components ?? []
|
|
78
|
+
if (a.length !== b.length) return false
|
|
79
|
+
for (let i = 0; i < a.length; i++) {
|
|
80
|
+
if (a[i] !== b[i]) return false
|
|
81
|
+
}
|
|
82
|
+
return prev.width === next.width && prev.height === next.height && prev.fillStyle === next.fillStyle
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The inverse of one operation, against the scene as it was before that operation ran.
|
|
87
|
+
*
|
|
88
|
+
* This is what makes undo possible for a proposed change: a host that applies ops one at a
|
|
89
|
+
* time and keeps the inverses can restore the scene by running them backwards.
|
|
90
|
+
*
|
|
91
|
+
* Returns null when the inverse cannot be known from the model alone. `add` is the clear
|
|
92
|
+
* case — its inverse needs the refid that things-scene issues on insert, so the host captures
|
|
93
|
+
* that itself. The scene-only operations are the same story: their result depends on
|
|
94
|
+
* coordinates and parenting that only the live scene knows.
|
|
95
|
+
*/
|
|
96
|
+
export function computeInverseOp(model: SceneModel | undefined, op: SceneEditOp): SceneEditOp | null {
|
|
97
|
+
if (!model) return null
|
|
98
|
+
const components = model.components ?? []
|
|
99
|
+
|
|
100
|
+
switch (op.op) {
|
|
101
|
+
case 'add':
|
|
102
|
+
return null
|
|
103
|
+
|
|
104
|
+
case 'remove': {
|
|
105
|
+
const target = findComponentDeep(components, op.refid)
|
|
106
|
+
if (!target) return null /* nothing was removed, so there is nothing to put back */
|
|
107
|
+
return { op: 'add', component: JSON.parse(JSON.stringify(target)) }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case 'modify': {
|
|
111
|
+
const target = findComponentDeep(components, op.refid)
|
|
112
|
+
if (!target) return null
|
|
113
|
+
/* Keep only the keys the patch touches; nested values are kept whole. */
|
|
114
|
+
const oldValues: any = {}
|
|
115
|
+
for (const k of Object.keys(op.patch || {})) {
|
|
116
|
+
const v = (target as any)[k]
|
|
117
|
+
oldValues[k] = v === undefined ? null : JSON.parse(JSON.stringify(v))
|
|
118
|
+
}
|
|
119
|
+
return { op: 'modify', refid: op.refid, patch: oldValues }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
case 'modifyScene': {
|
|
123
|
+
const oldValues: any = {}
|
|
124
|
+
const patch = op.patch || {}
|
|
125
|
+
for (const k of Object.keys(patch)) {
|
|
126
|
+
if (k === 'components') continue
|
|
127
|
+
const v = (model as any)[k]
|
|
128
|
+
oldValues[k] = v === undefined ? null : JSON.parse(JSON.stringify(v))
|
|
129
|
+
}
|
|
130
|
+
return { op: 'modifyScene', patch: oldValues }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
case 'replace':
|
|
134
|
+
return { op: 'replace', model: JSON.parse(JSON.stringify(model)) }
|
|
135
|
+
|
|
136
|
+
case 'zorder': {
|
|
137
|
+
/*
|
|
138
|
+
* forward ↔ backward and front ↔ back. front/back is best effort — sending something
|
|
139
|
+
* to the front and then to the back does not put it where it started. A host that needs
|
|
140
|
+
* an exact inverse captures the index beforehand and writes explicit modifies.
|
|
141
|
+
*/
|
|
142
|
+
const opp: Record<string, ZorderInverse> = {
|
|
143
|
+
forward: 'backward',
|
|
144
|
+
backward: 'forward',
|
|
145
|
+
front: 'back',
|
|
146
|
+
back: 'front'
|
|
147
|
+
}
|
|
148
|
+
const dir = opp[op.direction]
|
|
149
|
+
if (!dir) return null
|
|
150
|
+
return { op: 'zorder', refid: op.refid, direction: dir }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
case 'align':
|
|
154
|
+
case 'distribute':
|
|
155
|
+
case 'group':
|
|
156
|
+
case 'ungroup':
|
|
157
|
+
case 'arrange':
|
|
158
|
+
return null
|
|
159
|
+
|
|
160
|
+
default:
|
|
161
|
+
return null
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
type ZorderInverse = 'front' | 'back' | 'forward' | 'backward'
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The operations whose result only the live scene can produce — exact coordinates, refid
|
|
169
|
+
* issuing, reparenting. Simulating them here would give an answer that disagrees with what
|
|
170
|
+
* the user sees, so they do nothing and `apply-scene.ts` calls things-scene's own API.
|
|
171
|
+
*/
|
|
172
|
+
const SCENE_ONLY_OPS = new Set<SceneEditOp['op']>([
|
|
173
|
+
'align',
|
|
174
|
+
'distribute',
|
|
175
|
+
'group',
|
|
176
|
+
'ungroup',
|
|
177
|
+
'zorder',
|
|
178
|
+
'arrange'
|
|
179
|
+
])
|
|
180
|
+
|
|
181
|
+
export function applyOp(model: SceneModel, op: SceneEditOp): SceneModel {
|
|
182
|
+
const components = model.components ?? []
|
|
183
|
+
switch (op.op) {
|
|
184
|
+
case 'replace':
|
|
185
|
+
return op.model
|
|
186
|
+
|
|
187
|
+
case 'add':
|
|
188
|
+
/* Top level only — adding into a container is a separate operation we do not have yet. */
|
|
189
|
+
return { ...model, components: [...components, op.component] }
|
|
190
|
+
|
|
191
|
+
case 'remove':
|
|
192
|
+
return { ...model, components: removeComponentDeep(components, op.refid) }
|
|
193
|
+
|
|
194
|
+
case 'modify':
|
|
195
|
+
return { ...model, components: modifyComponentDeep(components, op.refid, op.patch) }
|
|
196
|
+
|
|
197
|
+
case 'modifyScene': {
|
|
198
|
+
/* Root properties only. `components` is ignored — children move by add/remove/modify. */
|
|
199
|
+
const patch = { ...op.patch } as any
|
|
200
|
+
delete patch.components
|
|
201
|
+
return mergeSceneRoot(model, patch)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
case 'align':
|
|
205
|
+
case 'distribute':
|
|
206
|
+
case 'group':
|
|
207
|
+
case 'ungroup':
|
|
208
|
+
case 'zorder':
|
|
209
|
+
case 'arrange':
|
|
210
|
+
return model
|
|
211
|
+
|
|
212
|
+
default:
|
|
213
|
+
return model
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* `null` in a patch means **remove this key**, not "set it to null".
|
|
219
|
+
*
|
|
220
|
+
* Three reasons this is the right reading:
|
|
221
|
+
* 1. Fields such as fillStyle and strokeStyle are `string | object | undefined`. Setting
|
|
222
|
+
* one to null walks straight into `typeof null === 'object'` downstream.
|
|
223
|
+
* 2. `computeInverseOp` emits null for a key the original did not have, which is exactly
|
|
224
|
+
* "remove it again" — so undo comes out right without a special case.
|
|
225
|
+
* 3. Clearing a field that a mode switch left behind is then just another key in the patch.
|
|
226
|
+
*
|
|
227
|
+
* A caller that genuinely wants to store null would need a new operation. Nothing in the
|
|
228
|
+
* scene model means anything by a stored null today.
|
|
229
|
+
*/
|
|
230
|
+
function mergeSceneRoot(model: SceneModel, patch: any): SceneModel {
|
|
231
|
+
const out: any = { ...model }
|
|
232
|
+
for (const key of Object.keys(patch)) {
|
|
233
|
+
const bv = (model as any)[key]
|
|
234
|
+
const pv = patch[key]
|
|
235
|
+
if (pv === null) {
|
|
236
|
+
delete out[key]
|
|
237
|
+
} else if (isPlainObject(bv) && isPlainObject(pv)) {
|
|
238
|
+
out[key] = deepMerge(bv, pv)
|
|
239
|
+
} else {
|
|
240
|
+
out[key] = pv
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return out
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Apply a partial patch to one component.
|
|
248
|
+
*
|
|
249
|
+
* Nested objects such as `threeD` are merged rather than replaced, so that changing a colour
|
|
250
|
+
* does not take the geometry with it. A null value removes the key, as above.
|
|
251
|
+
*/
|
|
252
|
+
export function mergeComponent(
|
|
253
|
+
base: SceneComponentModel,
|
|
254
|
+
patch: Partial<SceneComponentModel>
|
|
255
|
+
): SceneComponentModel {
|
|
256
|
+
const out: any = { ...base }
|
|
257
|
+
for (const key of Object.keys(patch)) {
|
|
258
|
+
const baseVal = (base as any)[key]
|
|
259
|
+
const patchVal = (patch as any)[key]
|
|
260
|
+
if (patchVal === null) {
|
|
261
|
+
delete out[key]
|
|
262
|
+
} else if (isPlainObject(baseVal) && isPlainObject(patchVal)) {
|
|
263
|
+
out[key] = deepMerge(baseVal, patchVal)
|
|
264
|
+
} else {
|
|
265
|
+
out[key] = patchVal
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return out as SceneComponentModel
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function deepMerge(a: any, b: any): any {
|
|
272
|
+
const out: any = { ...a }
|
|
273
|
+
for (const key of Object.keys(b)) {
|
|
274
|
+
const av = a[key]
|
|
275
|
+
const bv = b[key]
|
|
276
|
+
if (bv === null) {
|
|
277
|
+
delete out[key]
|
|
278
|
+
} else if (isPlainObject(av) && isPlainObject(bv)) {
|
|
279
|
+
out[key] = deepMerge(av, bv)
|
|
280
|
+
} else {
|
|
281
|
+
out[key] = bv
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return out
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function isPlainObject(v: any): boolean {
|
|
288
|
+
return v !== null && typeof v === 'object' && !Array.isArray(v)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* ── Reaching into containers ─────────────────────────────────────────────────────────── */
|
|
292
|
+
|
|
293
|
+
/** Find a component by refid anywhere in the tree, not only at the top level. */
|
|
294
|
+
function findComponentDeep(
|
|
295
|
+
components: SceneComponentModel[],
|
|
296
|
+
refid: number
|
|
297
|
+
): SceneComponentModel | undefined {
|
|
298
|
+
for (const c of components) {
|
|
299
|
+
if (!c) continue
|
|
300
|
+
if ((c as any).refid === refid) return c
|
|
301
|
+
const children = (c as any).components
|
|
302
|
+
if (Array.isArray(children) && children.length > 0) {
|
|
303
|
+
const sub = findComponentDeep(children, refid)
|
|
304
|
+
if (sub) return sub
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return undefined
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* `modify`, walking into containers. Branches that did not change come back as the same
|
|
312
|
+
* reference, so a caller can tell what moved by identity.
|
|
313
|
+
*/
|
|
314
|
+
function modifyComponentDeep(
|
|
315
|
+
components: SceneComponentModel[],
|
|
316
|
+
refid: number,
|
|
317
|
+
patch: any
|
|
318
|
+
): SceneComponentModel[] {
|
|
319
|
+
let changed = false
|
|
320
|
+
const out = components.map(c => {
|
|
321
|
+
if (!c) return c
|
|
322
|
+
if ((c as any).refid === refid) {
|
|
323
|
+
changed = true
|
|
324
|
+
return mergeComponent(c, patch)
|
|
325
|
+
}
|
|
326
|
+
const children = (c as any).components
|
|
327
|
+
if (Array.isArray(children) && children.length > 0) {
|
|
328
|
+
const updated = modifyComponentDeep(children, refid, patch)
|
|
329
|
+
if (updated !== children) {
|
|
330
|
+
changed = true
|
|
331
|
+
return { ...c, components: updated }
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return c
|
|
335
|
+
})
|
|
336
|
+
return changed ? out : components
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* `remove`, walking into containers. The parent stays, and a group left empty stays too —
|
|
341
|
+
* the user made that container on purpose and removing one child is not a reason to take it.
|
|
342
|
+
*/
|
|
343
|
+
function removeComponentDeep(
|
|
344
|
+
components: SceneComponentModel[],
|
|
345
|
+
refid: number
|
|
346
|
+
): SceneComponentModel[] {
|
|
347
|
+
let changed = false
|
|
348
|
+
const out: SceneComponentModel[] = []
|
|
349
|
+
for (const c of components) {
|
|
350
|
+
if (!c) {
|
|
351
|
+
out.push(c)
|
|
352
|
+
continue
|
|
353
|
+
}
|
|
354
|
+
if ((c as any).refid === refid) {
|
|
355
|
+
changed = true
|
|
356
|
+
continue
|
|
357
|
+
}
|
|
358
|
+
const children = (c as any).components
|
|
359
|
+
if (Array.isArray(children) && children.length > 0) {
|
|
360
|
+
const updated = removeComponentDeep(children, refid)
|
|
361
|
+
if (updated !== children) {
|
|
362
|
+
changed = true
|
|
363
|
+
out.push({ ...c, components: updated })
|
|
364
|
+
continue
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
out.push(c)
|
|
368
|
+
}
|
|
369
|
+
return changed ? out : components
|
|
370
|
+
}
|