@lix-js/sdk 0.4.7 → 0.5.0-preview.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/dist/account/create-account.d.ts +17 -3
- package/dist/account/create-account.d.ts.map +1 -1
- package/dist/account/create-account.js +27 -3
- package/dist/account/create-account.js.map +1 -1
- package/dist/account/create-account.test.js +42 -4
- package/dist/account/create-account.test.js.map +1 -1
- package/dist/account/index.d.ts +1 -1
- package/dist/account/index.d.ts.map +1 -1
- package/dist/account/index.js +1 -1
- package/dist/account/index.js.map +1 -1
- package/dist/account/schema.d.ts +28 -0
- package/dist/account/schema.d.ts.map +1 -0
- package/dist/account/schema.js +55 -0
- package/dist/account/schema.js.map +1 -0
- package/dist/account/schema.test.d.ts +2 -0
- package/dist/account/schema.test.d.ts.map +1 -0
- package/dist/account/schema.test.js +306 -0
- package/dist/account/schema.test.js.map +1 -0
- package/dist/account/switch-account.d.ts +2 -2
- package/dist/account/switch-account.d.ts.map +1 -1
- package/dist/account/switch-account.js +8 -1
- package/dist/account/switch-account.js.map +1 -1
- package/dist/account/switch-account.test.js +27 -6
- package/dist/account/switch-account.test.js.map +1 -1
- package/dist/change/create-change.d.ts +11 -22
- package/dist/change/create-change.d.ts.map +1 -1
- package/dist/change/create-change.js +29 -83
- package/dist/change/create-change.js.map +1 -1
- package/dist/change/create-change.test.js +129 -176
- package/dist/change/create-change.test.js.map +1 -1
- package/dist/change/index.d.ts +1 -2
- package/dist/change/index.d.ts.map +1 -1
- package/dist/change/index.js +1 -2
- package/dist/change/index.js.map +1 -1
- package/dist/change/mock-change.d.ts +1 -1
- package/dist/change/mock-change.d.ts.map +1 -1
- package/dist/change/mock-change.js +1 -0
- package/dist/change/mock-change.js.map +1 -1
- package/dist/change/schema.d.ts +28 -0
- package/dist/change/schema.d.ts.map +1 -0
- package/dist/change/schema.js +62 -0
- package/dist/change/schema.js.map +1 -0
- package/dist/change/schema.test.d.ts +2 -0
- package/dist/change/schema.test.d.ts.map +1 -0
- package/dist/change/schema.test.js +235 -0
- package/dist/change/schema.test.js.map +1 -0
- package/dist/change-author/index.d.ts +2 -0
- package/dist/change-author/index.d.ts.map +1 -0
- package/dist/change-author/index.js +2 -0
- package/dist/change-author/index.js.map +1 -0
- package/dist/change-author/schema.d.ts +31 -0
- package/dist/change-author/schema.d.ts.map +1 -0
- package/dist/change-author/schema.js +35 -0
- package/dist/change-author/schema.js.map +1 -0
- package/dist/change-author/schema.test.d.ts +2 -0
- package/dist/change-author/schema.test.d.ts.map +1 -0
- package/dist/change-author/schema.test.js +256 -0
- package/dist/change-author/schema.test.js.map +1 -0
- package/dist/change-conflict/create-change-conflict.d.ts.map +1 -1
- package/dist/change-conflict/create-change-conflict.js +24 -6
- package/dist/change-conflict/create-change-conflict.js.map +1 -1
- package/dist/change-conflict/create-change-conflict.test.js +13 -11
- package/dist/change-conflict/create-change-conflict.test.js.map +1 -1
- package/dist/change-conflict/detect-change-conflicts.d.ts.map +1 -1
- package/dist/change-conflict/detect-change-conflicts.js +2 -0
- package/dist/change-conflict/detect-change-conflicts.js.map +1 -1
- package/dist/change-conflict/detect-change-conflicts.test.js +17 -13
- package/dist/change-conflict/detect-change-conflicts.test.js.map +1 -1
- package/dist/change-conflict/detect-diverging-entity-conflict.d.ts.map +1 -1
- package/dist/change-conflict/detect-diverging-entity-conflict.js +3 -1
- package/dist/change-conflict/detect-diverging-entity-conflict.js.map +1 -1
- package/dist/change-conflict/detect-diverging-entity-conflict.test.js +23 -21
- package/dist/change-conflict/detect-diverging-entity-conflict.test.js.map +1 -1
- package/dist/change-conflict/garbage-collect-change-conflicts.d.ts.map +1 -1
- package/dist/change-conflict/garbage-collect-change-conflicts.js +2 -0
- package/dist/change-conflict/garbage-collect-change-conflicts.js.map +1 -1
- package/dist/change-conflict/garbage-collect-change-conflicts.test.js +15 -15
- package/dist/change-conflict/garbage-collect-change-conflicts.test.js.map +1 -1
- package/dist/change-conflict/resolve-conflict-by-selecting.d.ts.map +1 -1
- package/dist/change-conflict/resolve-conflict-by-selecting.js +2 -2
- package/dist/change-conflict/resolve-conflict-by-selecting.js.map +1 -1
- package/dist/change-conflict/resolve-conflict-by-selecting.test.js +17 -8
- package/dist/change-conflict/resolve-conflict-by-selecting.test.js.map +1 -1
- package/dist/change-proposal/create-change-proposal.d.ts +16 -0
- package/dist/change-proposal/create-change-proposal.d.ts.map +1 -0
- package/dist/change-proposal/create-change-proposal.js +52 -0
- package/dist/change-proposal/create-change-proposal.js.map +1 -0
- package/dist/change-proposal/create-change-proposal.test.d.ts +2 -0
- package/dist/change-proposal/create-change-proposal.test.d.ts.map +1 -0
- package/dist/change-proposal/create-change-proposal.test.js +91 -0
- package/dist/change-proposal/create-change-proposal.test.js.map +1 -0
- package/dist/change-proposal/database-schema.d.ts +13 -0
- package/dist/change-proposal/database-schema.d.ts.map +1 -0
- package/dist/change-proposal/database-schema.js +17 -0
- package/dist/change-proposal/database-schema.js.map +1 -0
- package/dist/change-proposal/database-schema.test.d.ts +2 -0
- package/dist/change-proposal/database-schema.test.d.ts.map +1 -0
- package/dist/change-proposal/database-schema.test.js +159 -0
- package/dist/change-proposal/database-schema.test.js.map +1 -0
- package/dist/change-proposal/index.d.ts +3 -0
- package/dist/change-proposal/index.d.ts.map +1 -0
- package/dist/change-proposal/index.js +3 -0
- package/dist/change-proposal/index.js.map +1 -0
- package/dist/change-set/apply-change-set.d.ts +10 -0
- package/dist/change-set/apply-change-set.d.ts.map +1 -0
- package/dist/change-set/apply-change-set.js +150 -0
- package/dist/change-set/apply-change-set.js.map +1 -0
- package/dist/change-set/apply-change-set.test.d.ts +2 -0
- package/dist/change-set/apply-change-set.test.d.ts.map +1 -0
- package/dist/change-set/apply-change-set.test.js +390 -0
- package/dist/change-set/apply-change-set.test.js.map +1 -0
- package/dist/change-set/change-set-element-in-symmetric-difference.d.ts.map +1 -1
- package/dist/change-set/create-change-set.d.ts +19 -18
- package/dist/change-set/create-change-set.d.ts.map +1 -1
- package/dist/change-set/create-change-set.js +95 -34
- package/dist/change-set/create-change-set.js.map +1 -1
- package/dist/change-set/create-change-set.test.js +109 -27
- package/dist/change-set/create-change-set.test.js.map +1 -1
- package/dist/change-set/create-checkpoint.d.ts +19 -0
- package/dist/change-set/create-checkpoint.d.ts.map +1 -0
- package/dist/change-set/create-checkpoint.js +86 -0
- package/dist/change-set/create-checkpoint.js.map +1 -0
- package/dist/change-set/create-checkpoint.test.d.ts +2 -0
- package/dist/change-set/create-checkpoint.test.d.ts.map +1 -0
- package/dist/change-set/create-checkpoint.test.js +294 -0
- package/dist/change-set/create-checkpoint.test.js.map +1 -0
- package/dist/change-set/create-merge-change-set.d.ts +23 -0
- package/dist/change-set/create-merge-change-set.d.ts.map +1 -0
- package/dist/change-set/create-merge-change-set.js +68 -0
- package/dist/change-set/create-merge-change-set.js.map +1 -0
- package/dist/change-set/create-merge-change-set.test.d.ts +2 -0
- package/dist/change-set/create-merge-change-set.test.d.ts.map +1 -0
- package/dist/change-set/create-merge-change-set.test.js +211 -0
- package/dist/change-set/create-merge-change-set.test.js.map +1 -0
- package/dist/change-set/create-transition-change-set.d.ts +18 -0
- package/dist/change-set/create-transition-change-set.d.ts.map +1 -0
- package/dist/change-set/create-transition-change-set.js +102 -0
- package/dist/change-set/create-transition-change-set.js.map +1 -0
- package/dist/change-set/create-transition-change-set.test.d.ts +2 -0
- package/dist/change-set/create-transition-change-set.test.d.ts.map +1 -0
- package/dist/change-set/create-transition-change-set.test.js +211 -0
- package/dist/change-set/create-transition-change-set.test.js.map +1 -0
- package/dist/change-set/create-undo-change-set.d.ts +27 -0
- package/dist/change-set/create-undo-change-set.d.ts.map +1 -0
- package/dist/change-set/create-undo-change-set.js +121 -0
- package/dist/change-set/create-undo-change-set.js.map +1 -0
- package/dist/change-set/create-undo-change-set.test.d.ts +2 -0
- package/dist/change-set/create-undo-change-set.test.d.ts.map +1 -0
- package/dist/change-set/create-undo-change-set.test.js +273 -0
- package/dist/change-set/create-undo-change-set.test.js.map +1 -0
- package/dist/change-set/index.d.ts +6 -1
- package/dist/change-set/index.d.ts.map +1 -1
- package/dist/change-set/index.js +6 -1
- package/dist/change-set/index.js.map +1 -1
- package/dist/change-set/schema.d.ts +149 -0
- package/dist/change-set/schema.d.ts.map +1 -0
- package/dist/change-set/schema.js +169 -0
- package/dist/change-set/schema.js.map +1 -0
- package/dist/change-set/schema.test.d.ts +2 -0
- package/dist/change-set/schema.test.d.ts.map +1 -0
- package/dist/change-set/schema.test.js +821 -0
- package/dist/change-set/schema.test.js.map +1 -0
- package/dist/database/execute-sync.d.ts +12 -6
- package/dist/database/execute-sync.d.ts.map +1 -1
- package/dist/database/execute-sync.js +25 -24
- package/dist/database/execute-sync.js.map +1 -1
- package/dist/database/execute-sync.test.js +53 -60
- package/dist/database/execute-sync.test.js.map +1 -1
- package/dist/database/graph-traversal-mode.d.ts +72 -0
- package/dist/database/graph-traversal-mode.d.ts.map +1 -0
- package/dist/database/graph-traversal-mode.js +2 -0
- package/dist/database/graph-traversal-mode.js.map +1 -0
- package/dist/database/index.d.ts +3 -2
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +3 -2
- package/dist/database/index.js.map +1 -1
- package/dist/database/init-db.d.ts +2 -0
- package/dist/database/init-db.d.ts.map +1 -1
- package/dist/database/init-db.js +69 -56
- package/dist/database/init-db.js.map +1 -1
- package/dist/database/kysely-plugin/json-column-plugin.d.ts +3 -0
- package/dist/database/kysely-plugin/json-column-plugin.d.ts.map +1 -0
- package/dist/database/kysely-plugin/json-column-plugin.js +168 -0
- package/dist/database/kysely-plugin/json-column-plugin.js.map +1 -0
- package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.d.ts.map +1 -1
- package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js +5 -10
- package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js.map +1 -1
- package/dist/database/kysely-plugin/parse-jsonb-plugin-v2.js +1 -1
- package/dist/database/kysely-plugin/parse-jsonb-plugin-v2.js.map +1 -1
- package/dist/database/kysely-plugin/serialize-jsonb-plugin.d.ts +14 -2
- package/dist/database/kysely-plugin/serialize-jsonb-plugin.d.ts.map +1 -1
- package/dist/database/kysely-plugin/serialize-jsonb-plugin.js +145 -74
- package/dist/database/kysely-plugin/serialize-jsonb-plugin.js.map +1 -1
- package/dist/database/kysely-plugin/serialize-jsonb-plugin.test.js +145 -1
- package/dist/database/kysely-plugin/serialize-jsonb-plugin.test.js.map +1 -1
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.d.ts +15 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.d.ts.map +1 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.js +31 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.js.map +1 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.d.ts +2 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.d.ts.map +1 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.js +51 -0
- package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.js.map +1 -0
- package/dist/database/schema.d.ts +42 -208
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/database/schema.js +35 -1
- package/dist/database/schema.js.map +1 -1
- package/dist/entity-views/entity-state-all.d.ts +217 -0
- package/dist/entity-views/entity-state-all.d.ts.map +1 -0
- package/dist/entity-views/entity-state-all.js +246 -0
- package/dist/entity-views/entity-state-all.js.map +1 -0
- package/dist/entity-views/entity-state-all.test.d.ts +2 -0
- package/dist/entity-views/entity-state-all.test.d.ts.map +1 -0
- package/dist/entity-views/entity-state-all.test.js +371 -0
- package/dist/entity-views/entity-state-all.test.js.map +1 -0
- package/dist/entity-views/entity-state-history.d.ts +178 -0
- package/dist/entity-views/entity-state-history.d.ts.map +1 -0
- package/dist/entity-views/entity-state-history.js +58 -0
- package/dist/entity-views/entity-state-history.js.map +1 -0
- package/dist/entity-views/entity-state-history.test.d.ts +2 -0
- package/dist/entity-views/entity-state-history.test.d.ts.map +1 -0
- package/dist/entity-views/entity-state-history.test.js +274 -0
- package/dist/entity-views/entity-state-history.test.js.map +1 -0
- package/dist/entity-views/entity-state.d.ts +217 -0
- package/dist/entity-views/entity-state.d.ts.map +1 -0
- package/dist/entity-views/entity-state.js +243 -0
- package/dist/entity-views/entity-state.js.map +1 -0
- package/dist/entity-views/entity-state.test.d.ts +2 -0
- package/dist/entity-views/entity-state.test.d.ts.map +1 -0
- package/dist/entity-views/entity-state.test.js +497 -0
- package/dist/entity-views/entity-state.test.js.map +1 -0
- package/dist/entity-views/entity-state_history.d.ts +67 -0
- package/dist/entity-views/entity-state_history.d.ts.map +1 -0
- package/dist/entity-views/entity-state_history.js +58 -0
- package/dist/entity-views/entity-state_history.js.map +1 -0
- package/dist/entity-views/entity-view-builder.d.ts +92 -0
- package/dist/entity-views/entity-view-builder.d.ts.map +1 -0
- package/dist/entity-views/entity-view-builder.js +63 -0
- package/dist/entity-views/entity-view-builder.js.map +1 -0
- package/dist/entity-views/entity-view-builder.test.d.ts +2 -0
- package/dist/entity-views/entity-view-builder.test.d.ts.map +1 -0
- package/dist/entity-views/entity-view-builder.test.js +247 -0
- package/dist/entity-views/entity-view-builder.test.js.map +1 -0
- package/dist/entity-views/generic-types.d.ts +128 -0
- package/dist/entity-views/generic-types.d.ts.map +1 -0
- package/dist/entity-views/generic-types.js +2 -0
- package/dist/entity-views/generic-types.js.map +1 -0
- package/dist/entity-views/generic-types.test.d.ts +2 -0
- package/dist/entity-views/generic-types.test.d.ts.map +1 -0
- package/dist/entity-views/generic-types.test.js +99 -0
- package/dist/entity-views/generic-types.test.js.map +1 -0
- package/dist/entity-views/index.d.ts +2 -0
- package/dist/entity-views/index.d.ts.map +1 -0
- package/dist/entity-views/index.js +2 -0
- package/dist/entity-views/index.js.map +1 -0
- package/dist/entity-views/types.d.ts +309 -0
- package/dist/entity-views/types.d.ts.map +1 -0
- package/dist/entity-views/types.js +2 -0
- package/dist/entity-views/types.js.map +1 -0
- package/dist/entity-views/types.test.d.ts +2 -0
- package/dist/entity-views/types.test.d.ts.map +1 -0
- package/dist/entity-views/types.test.js +62 -0
- package/dist/entity-views/types.test.js.map +1 -0
- package/dist/file/file-handlers.d.ts +15 -0
- package/dist/file/file-handlers.d.ts.map +1 -0
- package/dist/file/file-handlers.js +318 -0
- package/dist/file/file-handlers.js.map +1 -0
- package/dist/file/file-handlers.test.d.ts +2 -0
- package/dist/file/file-handlers.test.d.ts.map +1 -0
- package/dist/file/file-handlers.test.js +151 -0
- package/dist/file/file-handlers.test.js.map +1 -0
- package/dist/file/index.d.ts +1 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/file/materialize-file-data-at-changeset.d.ts +9 -0
- package/dist/file/materialize-file-data-at-changeset.d.ts.map +1 -0
- package/dist/file/materialize-file-data-at-changeset.js +93 -0
- package/dist/file/materialize-file-data-at-changeset.js.map +1 -0
- package/dist/file/materialize-file-data.d.ts +8 -0
- package/dist/file/materialize-file-data.d.ts.map +1 -0
- package/dist/file/materialize-file-data.js +91 -0
- package/dist/file/materialize-file-data.js.map +1 -0
- package/dist/file/materialize-file-data.test.d.ts +2 -0
- package/dist/file/materialize-file-data.test.d.ts.map +1 -0
- package/dist/file/materialize-file-data.test.js +90 -0
- package/dist/file/materialize-file-data.test.js.map +1 -0
- package/dist/file/schema.d.ts +46 -0
- package/dist/file/schema.d.ts.map +1 -0
- package/dist/file/schema.js +265 -0
- package/dist/file/schema.js.map +1 -0
- package/dist/file/schema.test.d.ts +2 -0
- package/dist/file/schema.test.d.ts.map +1 -0
- package/dist/file/schema.test.js +805 -0
- package/dist/file/schema.test.js.map +1 -0
- package/dist/file/store-detected-change-schema.d.ts +8 -0
- package/dist/file/store-detected-change-schema.d.ts.map +1 -0
- package/dist/file/store-detected-change-schema.js +41 -0
- package/dist/file/store-detected-change-schema.js.map +1 -0
- package/dist/file/store-detected-change-schema.test.d.ts +2 -0
- package/dist/file/store-detected-change-schema.test.d.ts.map +1 -0
- package/dist/file/store-detected-change-schema.test.js +211 -0
- package/dist/file/store-detected-change-schema.test.js.map +1 -0
- package/dist/file/unknown-file-fallback-plugin.d.ts +22 -0
- package/dist/file/unknown-file-fallback-plugin.d.ts.map +1 -0
- package/dist/file/unknown-file-fallback-plugin.js +73 -0
- package/dist/file/unknown-file-fallback-plugin.js.map +1 -0
- package/dist/file/unknown-file-fallback-plugin.test.d.ts +2 -0
- package/dist/file/unknown-file-fallback-plugin.test.d.ts.map +1 -0
- package/dist/file/unknown-file-fallback-plugin.test.js +305 -0
- package/dist/file/unknown-file-fallback-plugin.test.js.map +1 -0
- package/dist/hooks/create-hooks.d.ts +72 -0
- package/dist/hooks/create-hooks.d.ts.map +1 -0
- package/dist/hooks/create-hooks.js +29 -0
- package/dist/hooks/create-hooks.js.map +1 -0
- package/dist/hooks/create-hooks.test.d.ts +2 -0
- package/dist/hooks/create-hooks.test.d.ts.map +1 -0
- package/dist/hooks/create-hooks.test.js +98 -0
- package/dist/hooks/create-hooks.test.js.map +1 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/key-value/index.d.ts +2 -0
- package/dist/key-value/index.d.ts.map +1 -0
- package/dist/key-value/index.js +2 -0
- package/dist/key-value/index.js.map +1 -0
- package/dist/key-value/schema.d.ts +21 -0
- package/dist/key-value/schema.d.ts.map +1 -0
- package/dist/key-value/schema.js +25 -0
- package/dist/key-value/schema.js.map +1 -0
- package/dist/key-value/schema.test.d.ts +2 -0
- package/dist/key-value/schema.test.d.ts.map +1 -0
- package/dist/key-value/schema.test.js +148 -0
- package/dist/key-value/schema.test.js.map +1 -0
- package/dist/label/create-label.d.ts +20 -0
- package/dist/label/create-label.d.ts.map +1 -0
- package/dist/label/create-label.js +45 -0
- package/dist/label/create-label.js.map +1 -0
- package/dist/label/create-label.test.d.ts +2 -0
- package/dist/label/create-label.test.d.ts.map +1 -0
- package/dist/label/create-label.test.js +191 -0
- package/dist/label/create-label.test.js.map +1 -0
- package/dist/label/index.d.ts +3 -0
- package/dist/label/index.d.ts.map +1 -0
- package/dist/label/index.js +3 -0
- package/dist/label/index.js.map +1 -0
- package/dist/label/schema.d.ts +22 -0
- package/dist/label/schema.d.ts.map +1 -0
- package/dist/label/schema.js +28 -0
- package/dist/label/schema.js.map +1 -0
- package/dist/label/schema.test.d.ts +2 -0
- package/dist/label/schema.test.d.ts.map +1 -0
- package/dist/label/schema.test.js +76 -0
- package/dist/label/schema.test.js.map +1 -0
- package/dist/lix/close-lix.d.ts +10 -1
- package/dist/lix/close-lix.d.ts.map +1 -1
- package/dist/lix/close-lix.js +10 -1
- package/dist/lix/close-lix.js.map +1 -1
- package/dist/lix/index.d.ts +3 -3
- package/dist/lix/index.d.ts.map +1 -1
- package/dist/lix/index.js +3 -6
- package/dist/lix/index.js.map +1 -1
- package/dist/lix/new-lix.d.ts +77 -4
- package/dist/lix/new-lix.d.ts.map +1 -1
- package/dist/lix/new-lix.js +303 -8
- package/dist/lix/new-lix.js.map +1 -1
- package/dist/lix/new-lix.test.js +171 -16
- package/dist/lix/new-lix.test.js.map +1 -1
- package/dist/lix/open-lix-in-memory.d.ts +9 -1
- package/dist/lix/open-lix-in-memory.d.ts.map +1 -1
- package/dist/lix/open-lix-in-memory.js +15 -7
- package/dist/lix/open-lix-in-memory.js.map +1 -1
- package/dist/lix/open-lix-in-memory.test.js +0 -6
- package/dist/lix/open-lix-in-memory.test.js.map +1 -1
- package/dist/lix/open-lix.d.ts +68 -6
- package/dist/lix/open-lix.d.ts.map +1 -1
- package/dist/lix/open-lix.js +80 -14
- package/dist/lix/open-lix.js.map +1 -1
- package/dist/lix/open-lix.test.js +54 -22
- package/dist/lix/open-lix.test.js.map +1 -1
- package/dist/lix/storage/in-memory.d.ts +34 -0
- package/dist/lix/storage/in-memory.d.ts.map +1 -0
- package/dist/lix/storage/in-memory.js +57 -0
- package/dist/lix/storage/in-memory.js.map +1 -0
- package/dist/lix/storage/in-memory.test.d.ts +2 -0
- package/dist/lix/storage/in-memory.test.d.ts.map +1 -0
- package/dist/lix/storage/in-memory.test.js +146 -0
- package/dist/lix/storage/in-memory.test.js.map +1 -0
- package/dist/lix/storage/lix-storage-adapter.d.ts +16 -0
- package/dist/lix/storage/lix-storage-adapter.d.ts.map +1 -0
- package/dist/lix/storage/lix-storage-adapter.js +2 -0
- package/dist/lix/storage/lix-storage-adapter.js.map +1 -0
- package/dist/lix/storage/opfs.d.ts +66 -0
- package/dist/lix/storage/opfs.d.ts.map +1 -0
- package/dist/lix/storage/opfs.js +152 -0
- package/dist/lix/storage/opfs.js.map +1 -0
- package/dist/lix/storage/opfs.test.d.ts +2 -0
- package/dist/lix/storage/opfs.test.d.ts.map +1 -0
- package/dist/lix/storage/opfs.test.js +171 -0
- package/dist/lix/storage/opfs.test.js.map +1 -0
- package/dist/lix/to-blob.d.ts +9 -2
- package/dist/lix/to-blob.d.ts.map +1 -1
- package/dist/lix/to-blob.js +9 -2
- package/dist/lix/to-blob.js.map +1 -1
- package/dist/lix/to-blob.test.d.ts +2 -0
- package/dist/lix/to-blob.test.d.ts.map +1 -0
- package/dist/lix/to-blob.test.js +18 -0
- package/dist/lix/to-blob.test.js.map +1 -0
- package/dist/log/create-lix-own-log.d.ts +66 -0
- package/dist/log/create-lix-own-log.d.ts.map +1 -0
- package/dist/log/create-lix-own-log.js +103 -0
- package/dist/log/create-lix-own-log.js.map +1 -0
- package/dist/log/create-lix-own-log.test.d.ts +2 -0
- package/dist/log/create-lix-own-log.test.d.ts.map +1 -0
- package/dist/log/create-lix-own-log.test.js +81 -0
- package/dist/log/create-lix-own-log.test.js.map +1 -0
- package/dist/log/create-log.d.ts +32 -0
- package/dist/log/create-log.d.ts.map +1 -0
- package/dist/log/create-log.js +43 -0
- package/dist/log/create-log.js.map +1 -0
- package/dist/log/index.d.ts +3 -0
- package/dist/log/index.d.ts.map +1 -0
- package/dist/log/index.js +3 -0
- package/dist/log/index.js.map +1 -0
- package/dist/log/schema.d.ts +32 -0
- package/dist/log/schema.d.ts.map +1 -0
- package/dist/log/schema.js +43 -0
- package/dist/log/schema.js.map +1 -0
- package/dist/log/schema.test.d.ts +2 -0
- package/dist/log/schema.test.d.ts.map +1 -0
- package/dist/log/schema.test.js +119 -0
- package/dist/log/schema.test.js.map +1 -0
- package/dist/observe/create-observe.d.ts +17 -0
- package/dist/observe/create-observe.d.ts.map +1 -0
- package/dist/observe/create-observe.js +118 -0
- package/dist/observe/create-observe.js.map +1 -0
- package/dist/observe/create-observe.test.d.ts +2 -0
- package/dist/observe/create-observe.test.d.ts.map +1 -0
- package/dist/observe/create-observe.test.js +384 -0
- package/dist/observe/create-observe.test.js.map +1 -0
- package/dist/observe/index.d.ts +2 -0
- package/dist/observe/index.d.ts.map +1 -0
- package/dist/observe/index.js +2 -0
- package/dist/observe/index.js.map +1 -0
- package/dist/observe/lix-observable.d.ts +31 -0
- package/dist/observe/lix-observable.d.ts.map +1 -0
- package/dist/observe/lix-observable.js +65 -0
- package/dist/observe/lix-observable.js.map +1 -0
- package/dist/observe/lix-observable.test.d.ts +2 -0
- package/dist/observe/lix-observable.test.d.ts.map +1 -0
- package/dist/observe/lix-observable.test.js +187 -0
- package/dist/observe/lix-observable.test.js.map +1 -0
- package/dist/plugin/index.d.ts +2 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/lix-plugin.d.ts +24 -45
- package/dist/plugin/lix-plugin.d.ts.map +1 -1
- package/dist/plugin/lix-plugin.js +1 -1
- package/dist/plugin/lix-plugin.js.map +1 -1
- package/dist/plugin/lix-plugin.test-d.js +17 -11
- package/dist/plugin/lix-plugin.test-d.js.map +1 -1
- package/dist/plugin/mock-json-plugin.d.ts +17 -0
- package/dist/plugin/mock-json-plugin.d.ts.map +1 -0
- package/dist/plugin/mock-json-plugin.flatten.d.ts +3 -0
- package/dist/plugin/mock-json-plugin.flatten.d.ts.map +1 -0
- package/dist/plugin/mock-json-plugin.flatten.js +124 -0
- package/dist/plugin/mock-json-plugin.flatten.js.map +1 -0
- package/dist/plugin/mock-json-plugin.js +101 -0
- package/dist/plugin/mock-json-plugin.js.map +1 -0
- package/dist/plugin/mock-json-plugin.test.d.ts +2 -0
- package/dist/plugin/mock-json-plugin.test.d.ts.map +1 -0
- package/dist/plugin/mock-json-plugin.test.js +164 -0
- package/dist/plugin/mock-json-plugin.test.js.map +1 -0
- package/dist/query-filter/change-conflict-in-version.d.ts.map +1 -1
- package/dist/query-filter/change-has-label.d.ts +9 -3
- package/dist/query-filter/change-has-label.d.ts.map +1 -1
- package/dist/query-filter/change-has-label.js +7 -4
- package/dist/query-filter/change-has-label.js.map +1 -1
- package/dist/query-filter/change-has-label.test.js +36 -11
- package/dist/query-filter/change-has-label.test.js.map +1 -1
- package/dist/query-filter/change-is-leaf.d.ts.map +1 -1
- package/dist/query-filter/change-set-element-in-ancestry-of.d.ts +30 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.d.ts.map +1 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.js +46 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.js.map +1 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.test.d.ts +2 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.test.d.ts.map +1 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.test.js +323 -0
- package/dist/query-filter/change-set-element-in-ancestry-of.test.js.map +1 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.d.ts +20 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.d.ts.map +1 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.js +36 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.js.map +1 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.test.d.ts +2 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.test.d.ts.map +1 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.test.js +369 -0
- package/dist/query-filter/change-set-element-in-symmetric-difference.test.js.map +1 -0
- package/dist/query-filter/change-set-element-is-leaf-of.d.ts +29 -0
- package/dist/query-filter/change-set-element-is-leaf-of.d.ts.map +1 -0
- package/dist/query-filter/change-set-element-is-leaf-of.js +91 -0
- package/dist/query-filter/change-set-element-is-leaf-of.js.map +1 -0
- package/dist/query-filter/change-set-element-is-leaf-of.test.d.ts +2 -0
- package/dist/query-filter/change-set-element-is-leaf-of.test.d.ts.map +1 -0
- package/dist/query-filter/change-set-element-is-leaf-of.test.js +515 -0
- package/dist/query-filter/change-set-element-is-leaf-of.test.js.map +1 -0
- package/dist/query-filter/change-set-has-label.d.ts +19 -3
- package/dist/query-filter/change-set-has-label.d.ts.map +1 -1
- package/dist/query-filter/change-set-has-label.js +17 -4
- package/dist/query-filter/change-set-has-label.js.map +1 -1
- package/dist/query-filter/change-set-has-label.test.js +13 -20
- package/dist/query-filter/change-set-has-label.test.js.map +1 -1
- package/dist/query-filter/change-set-is-ancestor-of.d.ts +51 -0
- package/dist/query-filter/change-set-is-ancestor-of.d.ts.map +1 -0
- package/dist/query-filter/change-set-is-ancestor-of.js +63 -0
- package/dist/query-filter/change-set-is-ancestor-of.js.map +1 -0
- package/dist/query-filter/change-set-is-ancestor-of.test.d.ts +2 -0
- package/dist/query-filter/change-set-is-ancestor-of.test.d.ts.map +1 -0
- package/dist/query-filter/change-set-is-ancestor-of.test.js +153 -0
- package/dist/query-filter/change-set-is-ancestor-of.test.js.map +1 -0
- package/dist/query-filter/change-set-is-descendant-of.d.ts +44 -0
- package/dist/query-filter/change-set-is-descendant-of.d.ts.map +1 -0
- package/dist/query-filter/change-set-is-descendant-of.js +56 -0
- package/dist/query-filter/change-set-is-descendant-of.js.map +1 -0
- package/dist/query-filter/change-set-is-descendant-of.test.d.ts +2 -0
- package/dist/query-filter/change-set-is-descendant-of.test.d.ts.map +1 -0
- package/dist/query-filter/change-set-is-descendant-of.test.js +137 -0
- package/dist/query-filter/change-set-is-descendant-of.test.js.map +1 -0
- package/dist/query-filter/index.d.ts +5 -6
- package/dist/query-filter/index.d.ts.map +1 -1
- package/dist/query-filter/index.js +5 -6
- package/dist/query-filter/index.js.map +1 -1
- package/dist/query-filter/version-change-in-difference.d.ts.map +1 -1
- package/dist/query-filter/version-change-in-symmetric-difference.d.ts.map +1 -1
- package/dist/repository/comparison-example.js +173 -0
- package/dist/repository/comparison-example.js.map +1 -0
- package/dist/repository/entity-repository.d.ts +53 -0
- package/dist/repository/entity-repository.d.ts.map +1 -0
- package/dist/repository/entity-repository.js +187 -0
- package/dist/repository/entity-repository.js.map +1 -0
- package/dist/repository/entity-repository.test.d.ts +2 -0
- package/dist/repository/entity-repository.test.d.ts.map +1 -0
- package/dist/repository/entity-repository.test.js +94 -0
- package/dist/repository/entity-repository.test.js.map +1 -0
- package/dist/repository/example.d.ts +6 -0
- package/dist/repository/example.d.ts.map +1 -0
- package/dist/repository/example.js +87 -0
- package/dist/repository/example.js.map +1 -0
- package/dist/repository/file-repository.d.ts +39 -0
- package/dist/repository/file-repository.d.ts.map +1 -0
- package/dist/repository/file-repository.js +93 -0
- package/dist/repository/file-repository.js.map +1 -0
- package/dist/repository/file-repository.test.d.ts +2 -0
- package/dist/repository/file-repository.test.d.ts.map +1 -0
- package/dist/repository/file-repository.test.js +165 -0
- package/dist/repository/file-repository.test.js.map +1 -0
- package/dist/repository/index.d.ts +6 -0
- package/dist/repository/index.d.ts.map +1 -0
- package/dist/repository/index.js +6 -0
- package/dist/repository/index.js.map +1 -0
- package/dist/repository/integration.test.d.ts +2 -0
- package/dist/repository/integration.test.d.ts.map +1 -0
- package/dist/repository/integration.test.js +136 -0
- package/dist/repository/integration.test.js.map +1 -0
- package/dist/repository/key-value-repository.d.ts +30 -0
- package/dist/repository/key-value-repository.d.ts.map +1 -0
- package/dist/repository/key-value-repository.js +60 -0
- package/dist/repository/key-value-repository.js.map +1 -0
- package/dist/repository/key-value-repository.test.d.ts +2 -0
- package/dist/repository/key-value-repository.test.d.ts.map +1 -0
- package/dist/repository/key-value-repository.test.js +122 -0
- package/dist/repository/key-value-repository.test.js.map +1 -0
- package/dist/repository/markdown-plugin-example.js +118 -0
- package/dist/repository/markdown-plugin-example.js.map +1 -0
- package/dist/repository/query-builder.d.ts +69 -0
- package/dist/repository/query-builder.d.ts.map +1 -0
- package/dist/repository/query-builder.js +155 -0
- package/dist/repository/query-builder.js.map +1 -0
- package/dist/repository/query-builder.test.d.ts +2 -0
- package/dist/repository/query-builder.test.d.ts.map +1 -0
- package/dist/repository/query-builder.test.js +244 -0
- package/dist/repository/query-builder.test.js.map +1 -0
- package/dist/repository/repository-manager.d.ts +27 -0
- package/dist/repository/repository-manager.d.ts.map +1 -0
- package/dist/repository/repository-manager.js +19 -0
- package/dist/repository/repository-manager.js.map +1 -0
- package/dist/repository/repository-manager.test.d.ts +2 -0
- package/dist/repository/repository-manager.test.d.ts.map +1 -0
- package/dist/repository/repository-manager.test.js +65 -0
- package/dist/repository/repository-manager.test.js.map +1 -0
- package/dist/repository/test-helpers.js +402 -0
- package/dist/repository/test-helpers.js.map +1 -0
- package/dist/schema-definition/definition.d.ts +406 -0
- package/dist/schema-definition/definition.d.ts.map +1 -0
- package/dist/schema-definition/definition.js +82 -0
- package/dist/schema-definition/definition.js.map +1 -0
- package/dist/schema-definition/definition.test-d.d.ts +2 -0
- package/dist/schema-definition/definition.test-d.d.ts.map +1 -0
- package/dist/schema-definition/definition.test-d.js +177 -0
- package/dist/schema-definition/definition.test-d.js.map +1 -0
- package/dist/schema-definition/definition.test.d.ts +2 -0
- package/dist/schema-definition/definition.test.d.ts.map +1 -0
- package/dist/schema-definition/definition.test.js +324 -0
- package/dist/schema-definition/definition.test.js.map +1 -0
- package/dist/schema-definition/index.d.ts +4 -0
- package/dist/schema-definition/index.d.ts.map +1 -0
- package/dist/schema-definition/index.js +4 -0
- package/dist/schema-definition/index.js.map +1 -0
- package/dist/schema-definition/json-type.d.ts +24 -0
- package/dist/schema-definition/json-type.d.ts.map +1 -0
- package/dist/schema-definition/json-type.js +42 -0
- package/dist/schema-definition/json-type.js.map +1 -0
- package/dist/schema-definition/json-type.test.d.ts +2 -0
- package/dist/schema-definition/json-type.test.d.ts.map +1 -0
- package/dist/schema-definition/json-type.test.js +21 -0
- package/dist/schema-definition/json-type.test.js.map +1 -0
- package/dist/schema-definition/lix-generated.test.d.ts +2 -0
- package/dist/schema-definition/lix-generated.test.d.ts.map +1 -0
- package/dist/schema-definition/lix-generated.test.js +127 -0
- package/dist/schema-definition/lix-generated.test.js.map +1 -0
- package/dist/schema-definition/validate-lix-schema.d.ts +65 -0
- package/dist/schema-definition/validate-lix-schema.d.ts.map +1 -0
- package/dist/schema-definition/validate-lix-schema.js +93 -0
- package/dist/schema-definition/validate-lix-schema.js.map +1 -0
- package/dist/schema-definition/validate-lix-schema.test.d.ts +2 -0
- package/dist/schema-definition/validate-lix-schema.test.d.ts.map +1 -0
- package/dist/schema-definition/validate-lix-schema.test.js +73 -0
- package/dist/schema-definition/validate-lix-schema.test.js.map +1 -0
- package/dist/server-protocol-handler/create-server-protocol-handler.d.ts +0 -1
- package/dist/server-protocol-handler/create-server-protocol-handler.d.ts.map +1 -1
- package/dist/server-protocol-handler/create-server-protocol-handler.js +0 -2
- package/dist/server-protocol-handler/create-server-protocol-handler.js.map +1 -1
- package/dist/server-protocol-handler/environment/create-in-memory-environment.d.ts.map +1 -1
- package/dist/server-protocol-handler/environment/create-in-memory-environment.js +5 -20
- package/dist/server-protocol-handler/environment/create-in-memory-environment.js.map +1 -1
- package/dist/server-protocol-handler/environment/create-in-memory-environment.test.js +13 -14
- package/dist/server-protocol-handler/environment/create-in-memory-environment.test.js.map +1 -1
- package/dist/server-protocol-handler/environment/environment.d.ts +0 -4
- package/dist/server-protocol-handler/environment/environment.d.ts.map +1 -1
- package/dist/server-protocol-handler/routes/get-v1.d.ts.map +1 -1
- package/dist/server-protocol-handler/routes/get-v1.js +1 -1
- package/dist/server-protocol-handler/routes/get-v1.js.map +1 -1
- package/dist/server-protocol-handler/routes/get-v1.test.js +11 -12
- package/dist/server-protocol-handler/routes/get-v1.test.js.map +1 -1
- package/dist/server-protocol-handler/routes/new-v1.d.ts.map +1 -1
- package/dist/server-protocol-handler/routes/new-v1.js +3 -5
- package/dist/server-protocol-handler/routes/new-v1.js.map +1 -1
- package/dist/server-protocol-handler/routes/new-v1.test.js +7 -8
- package/dist/server-protocol-handler/routes/new-v1.test.js.map +1 -1
- package/dist/server-protocol-handler/routes/pull-v1.test.js +48 -32
- package/dist/server-protocol-handler/routes/pull-v1.test.js.map +1 -1
- package/dist/server-protocol-handler/routes/push-v1.d.ts.map +1 -1
- package/dist/server-protocol-handler/routes/push-v1.js +2 -0
- package/dist/server-protocol-handler/routes/push-v1.js.map +1 -1
- package/dist/server-protocol-handler/routes/push-v1.test.js +22 -26
- package/dist/server-protocol-handler/routes/push-v1.test.js.map +1 -1
- package/dist/services/env-variables/index.d.ts +1 -1
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/env-variables/index.js.map +1 -1
- package/dist/services/telemetry/capture.d.ts.map +1 -1
- package/dist/snapshot/create-snapshot.d.ts +3 -14
- package/dist/snapshot/create-snapshot.d.ts.map +1 -1
- package/dist/snapshot/create-snapshot.js +14 -19
- package/dist/snapshot/create-snapshot.js.map +1 -1
- package/dist/snapshot/create-snapshot.test.js +49 -20
- package/dist/snapshot/create-snapshot.test.js.map +1 -1
- package/dist/snapshot/index.d.ts +1 -0
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/snapshot/index.js +1 -0
- package/dist/snapshot/index.js.map +1 -1
- package/dist/snapshot/json-sha-256.d.ts +2 -1
- package/dist/snapshot/json-sha-256.d.ts.map +1 -1
- package/dist/snapshot/json-sha-256.js +1 -3
- package/dist/snapshot/json-sha-256.js.map +1 -1
- package/dist/snapshot/json-sha-256.test.js +40 -2
- package/dist/snapshot/json-sha-256.test.js.map +1 -1
- package/dist/snapshot/mock-json-snapshot.d.ts +1 -1
- package/dist/snapshot/mock-json-snapshot.d.ts.map +1 -1
- package/dist/snapshot/schema.d.ts +8 -0
- package/dist/snapshot/schema.d.ts.map +1 -0
- package/dist/snapshot/schema.js +12 -0
- package/dist/snapshot/schema.js.map +1 -0
- package/dist/snapshot/schema.test.d.ts +2 -0
- package/dist/snapshot/schema.test.d.ts.map +1 -0
- package/dist/snapshot/schema.test.js +116 -0
- package/dist/snapshot/schema.test.js.map +1 -0
- package/dist/state/create-changeset-for-transaction.d.ts +15 -0
- package/dist/state/create-changeset-for-transaction.d.ts.map +1 -0
- package/dist/state/create-changeset-for-transaction.js +237 -0
- package/dist/state/create-changeset-for-transaction.js.map +1 -0
- package/dist/state/entity-view-builder.d.ts +145 -0
- package/dist/state/entity-view-builder.d.ts.map +1 -0
- package/dist/state/entity-view-builder.js +280 -0
- package/dist/state/entity-view-builder.js.map +1 -0
- package/dist/state/entity-view-builder.test.d.ts +2 -0
- package/dist/state/entity-view-builder.test.d.ts.map +1 -0
- package/dist/state/entity-view-builder.test.js +523 -0
- package/dist/state/entity-view-builder.test.js.map +1 -0
- package/dist/state/get-version-record-by-id-or-throw.d.ts +6 -0
- package/dist/state/get-version-record-by-id-or-throw.d.ts.map +1 -0
- package/dist/state/get-version-record-by-id-or-throw.js +36 -0
- package/dist/state/get-version-record-by-id-or-throw.js.map +1 -0
- package/dist/state/handle-state-mutation.d.ts +18 -0
- package/dist/state/handle-state-mutation.d.ts.map +1 -0
- package/dist/state/handle-state-mutation.js +352 -0
- package/dist/state/handle-state-mutation.js.map +1 -0
- package/dist/state/handle-state-mutation.test.d.ts +2 -0
- package/dist/state/handle-state-mutation.test.d.ts.map +1 -0
- package/dist/state/handle-state-mutation.test.js +632 -0
- package/dist/state/handle-state-mutation.test.js.map +1 -0
- package/dist/state/schema.bench.d.ts +2 -0
- package/dist/state/schema.bench.d.ts.map +1 -0
- package/dist/state/schema.bench.js +36 -0
- package/dist/state/schema.bench.js.map +1 -0
- package/dist/state/schema.d.ts +56 -0
- package/dist/state/schema.d.ts.map +1 -0
- package/dist/state/schema.js +1052 -0
- package/dist/state/schema.js.map +1 -0
- package/dist/state/schema.test.d.ts +2 -0
- package/dist/state/schema.test.d.ts.map +1 -0
- package/dist/state/schema.test.js +2030 -0
- package/dist/state/schema.test.js.map +1 -0
- package/dist/state/validate-state-mutation.d.ts +13 -0
- package/dist/state/validate-state-mutation.d.ts.map +1 -0
- package/dist/state/validate-state-mutation.js +485 -0
- package/dist/state/validate-state-mutation.js.map +1 -0
- package/dist/state/validate-state-mutation.test.d.ts +2 -0
- package/dist/state/validate-state-mutation.test.d.ts.map +1 -0
- package/dist/state/validate-state-mutation.test.js +2024 -0
- package/dist/state/validate-state-mutation.test.js.map +1 -0
- package/dist/state-history/schema.d.ts +58 -0
- package/dist/state-history/schema.d.ts.map +1 -0
- package/dist/state-history/schema.js +104 -0
- package/dist/state-history/schema.js.map +1 -0
- package/dist/state-history/schema.test.d.ts +2 -0
- package/dist/state-history/schema.test.d.ts.map +1 -0
- package/dist/state-history/schema.test.js +701 -0
- package/dist/state-history/schema.test.js.map +1 -0
- package/dist/stored-schema/index.d.ts +2 -0
- package/dist/stored-schema/index.d.ts.map +1 -0
- package/dist/stored-schema/index.js +2 -0
- package/dist/stored-schema/index.js.map +1 -0
- package/dist/stored-schema/schema.d.ts +25 -0
- package/dist/stored-schema/schema.d.ts.map +1 -0
- package/dist/stored-schema/schema.js +48 -0
- package/dist/stored-schema/schema.js.map +1 -0
- package/dist/stored-schema/schema.test.d.ts +2 -0
- package/dist/stored-schema/schema.test.d.ts.map +1 -0
- package/dist/stored-schema/schema.test.js +192 -0
- package/dist/stored-schema/schema.test.js.map +1 -0
- package/dist/sync/get-diffing-rows.d.ts +12 -0
- package/dist/sync/get-diffing-rows.d.ts.map +1 -1
- package/dist/sync/get-diffing-rows.js +14 -0
- package/dist/sync/get-diffing-rows.js.map +1 -1
- package/dist/sync/merge-state.d.ts.map +1 -1
- package/dist/sync/merge-state.js +2 -1
- package/dist/sync/merge-state.js.map +1 -1
- package/dist/sync/pull-from-server.d.ts.map +1 -1
- package/dist/sync/pull-from-server.js +2 -1
- package/dist/sync/pull-from-server.js.map +1 -1
- package/dist/sync/pull-from-server.test.js +32 -28
- package/dist/sync/pull-from-server.test.js.map +1 -1
- package/dist/sync/push-to-server.d.ts +10 -1
- package/dist/sync/push-to-server.d.ts.map +1 -1
- package/dist/sync/push-to-server.js +10 -1
- package/dist/sync/push-to-server.js.map +1 -1
- package/dist/sync/push-to-server.test.js +62 -63
- package/dist/sync/push-to-server.test.js.map +1 -1
- package/dist/sync/sync-process.d.ts +1 -1
- package/dist/sync/sync-process.d.ts.map +1 -1
- package/dist/sync/sync-process.js +1 -2
- package/dist/sync/sync-process.js.map +1 -1
- package/dist/sync/sync-process.test.js +20 -17
- package/dist/sync/sync-process.test.js.map +1 -1
- package/dist/thread/create-thread-comment.d.ts +18 -0
- package/dist/thread/create-thread-comment.d.ts.map +1 -0
- package/dist/thread/create-thread-comment.js +47 -0
- package/dist/thread/create-thread-comment.js.map +1 -0
- package/dist/thread/create-thread-comment.test.d.ts +2 -0
- package/dist/thread/create-thread-comment.test.d.ts.map +1 -0
- package/dist/thread/create-thread-comment.test.js +51 -0
- package/dist/thread/create-thread-comment.test.js.map +1 -0
- package/dist/thread/create-thread.d.ts +28 -0
- package/dist/thread/create-thread.d.ts.map +1 -0
- package/dist/thread/create-thread.js +58 -0
- package/dist/thread/create-thread.js.map +1 -0
- package/dist/thread/create-thread.test.d.ts +2 -0
- package/dist/thread/create-thread.test.d.ts.map +1 -0
- package/dist/thread/create-thread.test.js +26 -0
- package/dist/thread/create-thread.test.js.map +1 -0
- package/dist/thread/index.d.ts +4 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/thread/index.js +4 -0
- package/dist/thread/index.js.map +1 -0
- package/dist/thread/schema.d.ts +59 -0
- package/dist/thread/schema.d.ts.map +1 -0
- package/dist/thread/schema.js +66 -0
- package/dist/thread/schema.js.map +1 -0
- package/dist/thread/schema.test.d.ts +2 -0
- package/dist/thread/schema.test.d.ts.map +1 -0
- package/dist/thread/schema.test.js +60 -0
- package/dist/thread/schema.test.js.map +1 -0
- package/dist/version/create-version.d.ts +9 -17
- package/dist/version/create-version.d.ts.map +1 -1
- package/dist/version/create-version.js +30 -57
- package/dist/version/create-version.js.map +1 -1
- package/dist/version/create-version.test.js +70 -113
- package/dist/version/create-version.test.js.map +1 -1
- package/dist/version/index.d.ts +1 -5
- package/dist/version/index.d.ts.map +1 -1
- package/dist/version/index.js +1 -5
- package/dist/version/index.js.map +1 -1
- package/dist/version/schema.d.ts +73 -0
- package/dist/version/schema.d.ts.map +1 -0
- package/dist/version/schema.js +135 -0
- package/dist/version/schema.js.map +1 -0
- package/dist/version/schema.test.d.ts +2 -0
- package/dist/version/schema.test.d.ts.map +1 -0
- package/dist/version/schema.test.js +661 -0
- package/dist/version/schema.test.js.map +1 -0
- package/dist/version/switch-version.d.ts +4 -4
- package/dist/version/switch-version.d.ts.map +1 -1
- package/dist/version/switch-version.js +6 -62
- package/dist/version/switch-version.js.map +1 -1
- package/dist/version/switch-version.test.js +14 -214
- package/dist/version/switch-version.test.js.map +1 -1
- package/dist/zettel-ast/index.d.ts +11 -0
- package/dist/zettel-ast/index.d.ts.map +1 -0
- package/dist/zettel-ast/index.js +11 -0
- package/dist/zettel-ast/index.js.map +1 -0
- package/package.json +10 -9
- package/src/account/create-account.test.ts +49 -4
- package/src/account/create-account.ts +36 -6
- package/src/account/index.ts +5 -1
- package/src/account/schema.test.ts +370 -0
- package/src/account/schema.ts +76 -0
- package/src/account/switch-account.test.ts +29 -6
- package/src/account/switch-account.ts +12 -3
- package/src/change/index.ts +1 -2
- package/src/change/schema.test.ts +284 -0
- package/src/change/schema.ts +93 -0
- package/src/change-author/index.ts +1 -0
- package/src/change-author/schema.test.ts +300 -0
- package/src/change-author/schema.ts +48 -0
- package/src/change-conflict/create-change-conflict.test.ts +14 -11
- package/src/change-conflict/create-change-conflict.ts +29 -6
- package/src/change-conflict/detect-change-conflicts.test.ts +18 -15
- package/src/change-conflict/detect-change-conflicts.ts +3 -0
- package/src/change-conflict/detect-diverging-entity-conflict.test.ts +24 -21
- package/src/change-conflict/detect-diverging-entity-conflict.ts +4 -1
- package/src/change-conflict/garbage-collect-change-conflicts.test.ts +16 -15
- package/src/change-conflict/garbage-collect-change-conflicts.ts +3 -0
- package/src/change-conflict/resolve-conflict-by-selecting.test.ts +18 -8
- package/src/change-conflict/resolve-conflict-by-selecting.ts +3 -2
- package/src/change-proposal/create-change-proposal.test.ts +106 -0
- package/src/change-proposal/create-change-proposal.ts +71 -0
- package/src/change-proposal/database-schema.test.ts +180 -0
- package/src/change-proposal/database-schema.ts +32 -0
- package/src/change-proposal/index.ts +2 -0
- package/src/change-set/apply-change-set.test.ts +469 -0
- package/src/change-set/apply-change-set.ts +186 -0
- package/src/change-set/create-change-set.test.ts +126 -27
- package/src/change-set/create-change-set.ts +117 -41
- package/src/change-set/create-checkpoint.test.ts +387 -0
- package/src/change-set/create-checkpoint.ts +101 -0
- package/src/change-set/create-merge-change-set.test.ts +237 -0
- package/src/change-set/create-merge-change-set.ts +99 -0
- package/src/change-set/create-transition-change-set.test.ts +245 -0
- package/src/change-set/create-transition-change-set.ts +149 -0
- package/src/change-set/create-undo-change-set.test.ts +329 -0
- package/src/change-set/create-undo-change-set.ts +147 -0
- package/src/change-set/index.ts +17 -1
- package/src/change-set/schema.test.ts +981 -0
- package/src/change-set/schema.ts +207 -0
- package/src/database/execute-sync.test.ts +60 -72
- package/src/database/execute-sync.ts +26 -27
- package/src/database/graph-traversal-mode.ts +75 -0
- package/src/database/index.ts +3 -2
- package/src/database/init-db.ts +82 -66
- package/src/database/kysely-plugin/json-column-plugin.ts +215 -0
- package/src/database/kysely-plugin/parse-jsonb-plugin-v1.ts +5 -10
- package/src/database/kysely-plugin/parse-jsonb-plugin-v2.ts +1 -1
- package/src/database/kysely-plugin/serialize-jsonb-plugin.test.ts +177 -2
- package/src/database/kysely-plugin/serialize-jsonb-plugin.ts +186 -87
- package/src/database/kysely-plugin/view-insert-returning-error-plugin.test.ts +62 -0
- package/src/database/kysely-plugin/view-insert-returning-error-plugin.ts +49 -0
- package/src/database/schema.ts +100 -267
- package/src/entity-views/entity-state-all.test.ts +445 -0
- package/src/entity-views/entity-state-all.ts +506 -0
- package/src/entity-views/entity-state-history.test.ts +325 -0
- package/src/entity-views/entity-state-history.ts +226 -0
- package/src/entity-views/entity-state.test.ts +592 -0
- package/src/entity-views/entity-state.ts +502 -0
- package/src/entity-views/entity-view-builder.test.ts +293 -0
- package/src/entity-views/entity-view-builder.ts +148 -0
- package/src/entity-views/index.ts +1 -0
- package/src/entity-views/types.test.ts +99 -0
- package/src/entity-views/types.ts +328 -0
- package/src/file/file-handlers.test.ts +174 -0
- package/src/file/file-handlers.ts +364 -0
- package/src/file/index.ts +5 -1
- package/src/file/materialize-file-data-at-changeset.ts +123 -0
- package/src/file/materialize-file-data.test.ts +107 -0
- package/src/file/materialize-file-data.ts +120 -0
- package/src/file/schema.test.ts +990 -0
- package/src/file/schema.ts +300 -0
- package/src/file/store-detected-change-schema.test.ts +248 -0
- package/src/file/store-detected-change-schema.ts +52 -0
- package/src/file/unknown-file-fallback-plugin.test.ts +368 -0
- package/src/file/unknown-file-fallback-plugin.ts +95 -0
- package/src/hooks/create-hooks.test.ts +125 -0
- package/src/hooks/create-hooks.ts +101 -0
- package/src/hooks/index.ts +1 -0
- package/src/index.ts +10 -6
- package/src/key-value/index.ts +1 -0
- package/src/key-value/schema.test.ts +179 -0
- package/src/key-value/schema.ts +37 -0
- package/src/label/create-label.test.ts +234 -0
- package/src/label/create-label.ts +61 -0
- package/src/label/index.ts +2 -0
- package/src/label/schema.test.ts +92 -0
- package/src/label/schema.ts +40 -0
- package/src/lix/index.ts +3 -6
- package/src/lix/new-lix.test.ts +213 -17
- package/src/lix/new-lix.ts +395 -8
- package/src/lix/open-lix.test.ts +65 -26
- package/src/lix/open-lix.ts +131 -22
- package/src/lix/storage/in-memory.test.ts +180 -0
- package/src/lix/storage/in-memory.ts +69 -0
- package/src/lix/storage/lix-storage-adapter.ts +16 -0
- package/src/lix/storage/opfs.test.ts +215 -0
- package/src/lix/storage/opfs.ts +175 -0
- package/src/log/create-lix-own-log.test.ts +119 -0
- package/src/log/create-lix-own-log.ts +124 -0
- package/src/log/create-log.ts +52 -0
- package/src/log/index.ts +2 -0
- package/src/log/schema.test.ts +140 -0
- package/src/log/schema.ts +55 -0
- package/src/observe/create-observe.test.ts +501 -0
- package/src/observe/create-observe.ts +146 -0
- package/src/observe/index.ts +1 -0
- package/src/observe/lix-observable.test.ts +247 -0
- package/src/observe/lix-observable.ts +92 -0
- package/src/plugin/index.ts +2 -2
- package/src/plugin/lix-plugin.test-d.ts +26 -15
- package/src/plugin/lix-plugin.ts +41 -50
- package/src/plugin/mock-json-plugin.flatten.ts +161 -0
- package/src/plugin/mock-json-plugin.test.ts +214 -0
- package/src/plugin/mock-json-plugin.ts +113 -0
- package/src/query-filter/change-has-label.test.ts +38 -11
- package/src/query-filter/change-has-label.ts +8 -4
- package/src/query-filter/change-set-element-in-ancestry-of.test.ts +354 -0
- package/src/query-filter/change-set-element-in-ancestry-of.ts +64 -0
- package/src/query-filter/change-set-element-in-symmetric-difference.test.ts +410 -0
- package/src/{change-set → query-filter}/change-set-element-in-symmetric-difference.ts +2 -1
- package/src/query-filter/change-set-element-is-leaf-of.test.ts +564 -0
- package/src/query-filter/change-set-element-is-leaf-of.ts +110 -0
- package/src/query-filter/change-set-has-label.test.ts +13 -21
- package/src/query-filter/change-set-has-label.ts +18 -4
- package/src/query-filter/change-set-is-ancestor-of.test.ts +178 -0
- package/src/query-filter/change-set-is-ancestor-of.ts +77 -0
- package/src/query-filter/change-set-is-descendant-of.test.ts +169 -0
- package/src/query-filter/change-set-is-descendant-of.ts +70 -0
- package/src/query-filter/index.ts +5 -6
- package/src/schema-definition/definition.test-d.ts +253 -0
- package/src/schema-definition/definition.test.ts +377 -0
- package/src/schema-definition/definition.ts +445 -0
- package/src/schema-definition/index.ts +13 -0
- package/src/schema-definition/json-type.test.ts +30 -0
- package/src/schema-definition/json-type.ts +53 -0
- package/src/schema-definition/validate-lix-schema.test.ts +85 -0
- package/src/schema-definition/validate-lix-schema.ts +108 -0
- package/src/server-protocol-handler/create-server-protocol-handler.ts +0 -4
- package/src/server-protocol-handler/environment/create-in-memory-environment.test.ts +13 -14
- package/src/server-protocol-handler/environment/create-in-memory-environment.ts +5 -24
- package/src/server-protocol-handler/environment/environment.ts +0 -5
- package/src/server-protocol-handler/routes/get-v1.test.ts +11 -12
- package/src/server-protocol-handler/routes/get-v1.ts +3 -1
- package/src/server-protocol-handler/routes/new-v1.test.ts +7 -8
- package/src/server-protocol-handler/routes/new-v1.ts +3 -5
- package/src/server-protocol-handler/routes/pull-v1.test.ts +49 -33
- package/src/server-protocol-handler/routes/pull-v1.ts +1 -1
- package/src/server-protocol-handler/routes/push-v1.test.ts +26 -27
- package/src/server-protocol-handler/routes/push-v1.ts +4 -1
- package/src/snapshot/schema.test.ts +155 -0
- package/src/snapshot/schema.ts +21 -0
- package/src/state/create-changeset-for-transaction.ts +321 -0
- package/src/state/get-version-record-by-id-or-throw.ts +51 -0
- package/src/state/handle-state-mutation.test.ts +761 -0
- package/src/state/handle-state-mutation.ts +418 -0
- package/src/state/schema.bench.ts +43 -0
- package/src/state/schema.test.ts +2416 -0
- package/src/state/schema.ts +1288 -0
- package/src/state/validate-state-mutation.test.ts +2353 -0
- package/src/state/validate-state-mutation.ts +664 -0
- package/src/state-history/schema.test.ts +827 -0
- package/src/state-history/schema.ts +198 -0
- package/src/stored-schema/index.ts +1 -0
- package/src/stored-schema/schema.test.ts +240 -0
- package/src/stored-schema/schema.ts +67 -0
- package/src/sync/get-diffing-rows.ts +16 -0
- package/src/sync/merge-state.ts +7 -4
- package/src/sync/pull-from-server.test.ts +33 -28
- package/src/sync/pull-from-server.ts +4 -2
- package/src/sync/push-to-server.test.ts +77 -81
- package/src/sync/push-to-server.ts +11 -2
- package/src/sync/sync-process.test.ts +21 -18
- package/src/sync/sync-process.ts +2 -3
- package/src/thread/create-thread-comment.test.ts +63 -0
- package/src/thread/create-thread-comment.ts +56 -0
- package/src/thread/create-thread.test.ts +32 -0
- package/src/thread/create-thread.ts +83 -0
- package/src/thread/index.ts +8 -0
- package/src/thread/schema.test.ts +76 -0
- package/src/thread/schema.ts +85 -0
- package/src/version/create-version.test.ts +78 -125
- package/src/version/create-version.ts +37 -64
- package/src/version/index.ts +5 -6
- package/src/version/schema.test.ts +794 -0
- package/src/version/schema.ts +149 -0
- package/src/version/switch-version.test.ts +14 -275
- package/src/version/switch-version.ts +8 -78
- package/src/zettel-ast/index.ts +10 -0
- package/src/account/database-schema.test.ts +0 -184
- package/src/account/database-schema.ts +0 -54
- package/src/change/apply-changes.test.ts +0 -268
- package/src/change/apply-changes.ts +0 -114
- package/src/change/create-change.test.ts +0 -296
- package/src/change/create-change.ts +0 -129
- package/src/change/mock-change.ts +0 -21
- package/src/change-schema/README.md +0 -3
- package/src/change-schema/index.ts +0 -4
- package/src/change-schema/types.test-d.ts +0 -52
- package/src/change-schema/types.ts +0 -53
- package/src/change-set/change-set-element-in-symmetric-difference.test.ts +0 -128
- package/src/database/apply-schema.ts +0 -272
- package/src/database/init-db.test.ts +0 -626
- package/src/database/mutation-log/database-schema.ts +0 -128
- package/src/database/mutation-log/lix-session.ts +0 -19
- package/src/discussion/create-comment.ts +0 -18
- package/src/discussion/create-discussion.test.ts +0 -45
- package/src/discussion/create-discussion.ts +0 -48
- package/src/discussion/index.ts +0 -2
- package/src/file/validate-file-path.test.ts +0 -44
- package/src/file/validate-file-path.ts +0 -60
- package/src/file-queue/file-handlers.ts +0 -267
- package/src/file-queue/file-queue-process.test.ts +0 -456
- package/src/file-queue/file-queue-process.ts +0 -108
- package/src/file-queue/file-queue-settled.test.ts +0 -56
- package/src/file-queue/file-queue-settled.ts +0 -31
- package/src/file-queue/index.ts +0 -1
- package/src/file-queue/with-skip-file-queue.test.ts +0 -158
- package/src/file-queue/with-skip-file-queue.ts +0 -33
- package/src/key-value/database-schema.test.ts +0 -140
- package/src/key-value/database-schema.ts +0 -66
- package/src/lix/close-lix.ts +0 -8
- package/src/lix/merge.get-leaf-changes-only-in-source.test.ts +0 -143
- package/src/lix/merge.get-leaf-changes-only-in-source.ts +0 -46
- package/src/lix/merge.test.ts +0 -858
- package/src/lix/merge.ts +0 -244
- package/src/lix/open-lix-in-memory.test.ts +0 -34
- package/src/lix/open-lix-in-memory.ts +0 -28
- package/src/lix/to-blob.ts +0 -14
- package/src/own-change-control/apply-own-change.test.ts +0 -361
- package/src/own-change-control/apply-own-change.ts +0 -110
- package/src/own-change-control/change-controlled-tables.test.ts +0 -69
- package/src/own-change-control/change-controlled-tables.ts +0 -102
- package/src/own-change-control/database-triggers.test.ts +0 -259
- package/src/own-change-control/database-triggers.ts +0 -189
- package/src/own-change-control/index.ts +0 -1
- package/src/own-change-control/with-skip-own-change-control.test.ts +0 -57
- package/src/own-change-control/with-skip-own-change-control.ts +0 -34
- package/src/plugin/load-plugin.ts +0 -37
- package/src/plugin/with-transaction.ts +0 -22
- package/src/query-filter/change-conflict-in-version.test.ts +0 -62
- package/src/query-filter/change-conflict-in-version.ts +0 -25
- package/src/query-filter/change-in-version.test.ts +0 -82
- package/src/query-filter/change-in-version.ts +0 -31
- package/src/query-filter/change-is-leaf-in-version.test.ts +0 -77
- package/src/query-filter/change-is-leaf-in-version.ts +0 -36
- package/src/query-filter/change-is-leaf-of.bench.ts +0 -175
- package/src/query-filter/change-is-leaf-of.test.ts +0 -84
- package/src/query-filter/change-is-leaf-of.ts +0 -46
- package/src/query-filter/change-is-leaf.test.ts +0 -140
- package/src/query-filter/change-is-leaf.ts +0 -25
- package/src/query-filter/change-is-lowest-common-ancestor-of.test.ts +0 -173
- package/src/query-filter/change-is-lowest-common-ancestor-of.ts +0 -57
- package/src/query-filter/version-change-in-difference.test.ts +0 -105
- package/src/query-filter/version-change-in-difference.ts +0 -37
- package/src/query-filter/version-change-in-symmetric-difference.test.ts +0 -104
- package/src/query-filter/version-change-in-symmetric-difference.ts +0 -52
- package/src/snapshot/create-snapshot.test.ts +0 -68
- package/src/snapshot/create-snapshot.ts +0 -40
- package/src/snapshot/index.ts +0 -2
- package/src/snapshot/json-sha-256.test.ts +0 -12
- package/src/snapshot/json-sha-256.ts +0 -35
- package/src/snapshot/mock-json-snapshot.ts +0 -14
- package/src/version/merge-version.test.ts +0 -530
- package/src/version/merge-version.ts +0 -88
- package/src/version/update-changes-in-version.test.ts +0 -371
- package/src/version/update-changes-in-version.ts +0 -47
|
@@ -0,0 +1,2030 @@
|
|
|
1
|
+
import { test, expect, describe } from "vitest";
|
|
2
|
+
import { openLix } from "../lix/open-lix.js";
|
|
3
|
+
import { Kysely, sql } from "kysely";
|
|
4
|
+
import { createVersion } from "../version/create-version.js";
|
|
5
|
+
test("select, insert, update, delete entity", async () => {
|
|
6
|
+
const mockSchema = {
|
|
7
|
+
"x-lix-key": "mock_schema",
|
|
8
|
+
"x-lix-version": "1.0",
|
|
9
|
+
type: "object",
|
|
10
|
+
additionalProperties: false,
|
|
11
|
+
properties: {
|
|
12
|
+
value: {
|
|
13
|
+
type: "string",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const lix = await openLix({});
|
|
18
|
+
await lix.db
|
|
19
|
+
.insertInto("stored_schema")
|
|
20
|
+
.values({ value: mockSchema })
|
|
21
|
+
.execute();
|
|
22
|
+
await lix.db
|
|
23
|
+
.insertInto("state_all")
|
|
24
|
+
.values({
|
|
25
|
+
entity_id: "e0",
|
|
26
|
+
file_id: "f0",
|
|
27
|
+
schema_key: "mock_schema",
|
|
28
|
+
plugin_key: "lix_own_entity",
|
|
29
|
+
schema_version: "1.0",
|
|
30
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
31
|
+
snapshot_content: {
|
|
32
|
+
value: "hello world",
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
.execute();
|
|
36
|
+
const viewAfterInsert = await lix.db
|
|
37
|
+
.selectFrom("state_all")
|
|
38
|
+
.where("schema_key", "=", "mock_schema")
|
|
39
|
+
.selectAll()
|
|
40
|
+
.execute();
|
|
41
|
+
expect(viewAfterInsert).toMatchObject([
|
|
42
|
+
{
|
|
43
|
+
entity_id: "e0",
|
|
44
|
+
file_id: "f0",
|
|
45
|
+
schema_key: "mock_schema",
|
|
46
|
+
plugin_key: "lix_own_entity",
|
|
47
|
+
snapshot_content: {
|
|
48
|
+
value: "hello world",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
]);
|
|
52
|
+
await lix.db
|
|
53
|
+
.updateTable("state_all")
|
|
54
|
+
.set({
|
|
55
|
+
snapshot_content: {
|
|
56
|
+
value: "hello world - updated",
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
.where("entity_id", "=", "e0")
|
|
60
|
+
.where("schema_key", "=", "mock_schema")
|
|
61
|
+
.where("file_id", "=", "f0")
|
|
62
|
+
.execute();
|
|
63
|
+
const viewAfterUpdate = await lix.db
|
|
64
|
+
.selectFrom("state_all")
|
|
65
|
+
.where("schema_key", "=", "mock_schema")
|
|
66
|
+
.selectAll()
|
|
67
|
+
.execute();
|
|
68
|
+
expect(viewAfterUpdate).toMatchObject([
|
|
69
|
+
{
|
|
70
|
+
entity_id: "e0",
|
|
71
|
+
file_id: "f0",
|
|
72
|
+
schema_key: "mock_schema",
|
|
73
|
+
plugin_key: "lix_own_entity",
|
|
74
|
+
snapshot_content: {
|
|
75
|
+
value: "hello world - updated",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
]);
|
|
79
|
+
await lix.db
|
|
80
|
+
.deleteFrom("state_all")
|
|
81
|
+
.where("entity_id", "=", "e0")
|
|
82
|
+
.where("version_id", "=", lix.db.selectFrom("active_version").select("version_id"))
|
|
83
|
+
.where("schema_key", "=", "mock_schema")
|
|
84
|
+
.execute();
|
|
85
|
+
const viewAfterDelete = await lix.db
|
|
86
|
+
.selectFrom("state_all")
|
|
87
|
+
.where("schema_key", "=", "mock_schema")
|
|
88
|
+
.selectAll()
|
|
89
|
+
.execute();
|
|
90
|
+
expect(viewAfterDelete).toHaveLength(0);
|
|
91
|
+
});
|
|
92
|
+
test("validates the schema on insert", async () => {
|
|
93
|
+
const lix = await openLix({});
|
|
94
|
+
const mockSchema = {
|
|
95
|
+
"x-lix-key": "mock_schema",
|
|
96
|
+
"x-lix-version": "1.0",
|
|
97
|
+
type: "object",
|
|
98
|
+
additionalProperties: false,
|
|
99
|
+
properties: {
|
|
100
|
+
value: {
|
|
101
|
+
type: "number",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
await lix.db
|
|
106
|
+
.insertInto("stored_schema")
|
|
107
|
+
.values({ value: mockSchema })
|
|
108
|
+
.execute();
|
|
109
|
+
await expect(lix.db
|
|
110
|
+
.insertInto("state_all")
|
|
111
|
+
.values({
|
|
112
|
+
entity_id: "e0",
|
|
113
|
+
file_id: "f0",
|
|
114
|
+
schema_key: "mock_schema",
|
|
115
|
+
plugin_key: "lix_own_entity",
|
|
116
|
+
schema_version: "1.0",
|
|
117
|
+
snapshot_content: {
|
|
118
|
+
value: "hello world",
|
|
119
|
+
},
|
|
120
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
121
|
+
})
|
|
122
|
+
.execute()).rejects.toThrow(/value must be number/);
|
|
123
|
+
});
|
|
124
|
+
test("validates the schema on update", async () => {
|
|
125
|
+
const lix = await openLix({});
|
|
126
|
+
const mockSchema = {
|
|
127
|
+
"x-lix-key": "mock_schema",
|
|
128
|
+
"x-lix-version": "1.0",
|
|
129
|
+
type: "object",
|
|
130
|
+
additionalProperties: false,
|
|
131
|
+
properties: {
|
|
132
|
+
value: {
|
|
133
|
+
type: "number",
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
await lix.db
|
|
138
|
+
.insertInto("stored_schema")
|
|
139
|
+
.values({ value: mockSchema })
|
|
140
|
+
.execute();
|
|
141
|
+
await lix.db
|
|
142
|
+
.insertInto("state_all")
|
|
143
|
+
.values({
|
|
144
|
+
entity_id: "e0",
|
|
145
|
+
file_id: "f0",
|
|
146
|
+
schema_key: "mock_schema",
|
|
147
|
+
plugin_key: "lix_own_entity",
|
|
148
|
+
schema_version: "1.0",
|
|
149
|
+
snapshot_content: {
|
|
150
|
+
value: 5,
|
|
151
|
+
},
|
|
152
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
153
|
+
})
|
|
154
|
+
.execute();
|
|
155
|
+
await expect(lix.db
|
|
156
|
+
.updateTable("state_all")
|
|
157
|
+
.set({
|
|
158
|
+
snapshot_content: {
|
|
159
|
+
value: "hello world - updated",
|
|
160
|
+
},
|
|
161
|
+
})
|
|
162
|
+
.where("entity_id", "=", "e0")
|
|
163
|
+
.where("schema_key", "=", "mock_schema")
|
|
164
|
+
.where("file_id", "=", "f0")
|
|
165
|
+
.execute()).rejects.toThrow(/value must be number/);
|
|
166
|
+
const viewAfterFailedUpdate = await lix.db
|
|
167
|
+
.selectFrom("state_all")
|
|
168
|
+
.where("schema_key", "=", "mock_schema")
|
|
169
|
+
.selectAll()
|
|
170
|
+
.execute();
|
|
171
|
+
expect(viewAfterFailedUpdate).toMatchObject([
|
|
172
|
+
{
|
|
173
|
+
entity_id: "e0",
|
|
174
|
+
file_id: "f0",
|
|
175
|
+
schema_key: "mock_schema",
|
|
176
|
+
plugin_key: "lix_own_entity",
|
|
177
|
+
snapshot_content: {
|
|
178
|
+
value: 5,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
182
|
+
});
|
|
183
|
+
test("state is separated by version", async () => {
|
|
184
|
+
const lix = await openLix({});
|
|
185
|
+
await createVersion({ lix, id: "version_a" });
|
|
186
|
+
await createVersion({ lix, id: "version_b" });
|
|
187
|
+
await lix.db
|
|
188
|
+
.insertInto("state_all")
|
|
189
|
+
.values([
|
|
190
|
+
{
|
|
191
|
+
entity_id: "e0",
|
|
192
|
+
file_id: "f0",
|
|
193
|
+
schema_key: "mock_schema",
|
|
194
|
+
plugin_key: "mock_plugin",
|
|
195
|
+
schema_version: "1.0",
|
|
196
|
+
snapshot_content: {
|
|
197
|
+
value: "hello world from version a",
|
|
198
|
+
},
|
|
199
|
+
version_id: "version_a",
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
entity_id: "e0",
|
|
203
|
+
file_id: "f0",
|
|
204
|
+
schema_key: "mock_schema",
|
|
205
|
+
plugin_key: "mock_plugin",
|
|
206
|
+
schema_version: "1.0",
|
|
207
|
+
snapshot_content: {
|
|
208
|
+
value: "hello world from version b",
|
|
209
|
+
},
|
|
210
|
+
version_id: "version_b",
|
|
211
|
+
},
|
|
212
|
+
])
|
|
213
|
+
.execute();
|
|
214
|
+
const stateAfterInserts = await lix.db
|
|
215
|
+
.selectFrom("state_all")
|
|
216
|
+
.where("schema_key", "=", "mock_schema")
|
|
217
|
+
.where("entity_id", "=", "e0")
|
|
218
|
+
.selectAll()
|
|
219
|
+
.execute();
|
|
220
|
+
expect(stateAfterInserts).toMatchObject([
|
|
221
|
+
{
|
|
222
|
+
entity_id: "e0",
|
|
223
|
+
file_id: "f0",
|
|
224
|
+
schema_key: "mock_schema",
|
|
225
|
+
plugin_key: "mock_plugin",
|
|
226
|
+
snapshot_content: {
|
|
227
|
+
value: "hello world from version a",
|
|
228
|
+
},
|
|
229
|
+
version_id: "version_a",
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
entity_id: "e0",
|
|
233
|
+
file_id: "f0",
|
|
234
|
+
schema_key: "mock_schema",
|
|
235
|
+
plugin_key: "mock_plugin",
|
|
236
|
+
snapshot_content: {
|
|
237
|
+
value: "hello world from version b",
|
|
238
|
+
},
|
|
239
|
+
version_id: "version_b",
|
|
240
|
+
},
|
|
241
|
+
]);
|
|
242
|
+
// Verify timestamps are present
|
|
243
|
+
expect(stateAfterInserts[0]?.created_at).toBeDefined();
|
|
244
|
+
expect(stateAfterInserts[0]?.updated_at).toBeDefined();
|
|
245
|
+
expect(stateAfterInserts[1]?.created_at).toBeDefined();
|
|
246
|
+
expect(stateAfterInserts[1]?.updated_at).toBeDefined();
|
|
247
|
+
await lix.db
|
|
248
|
+
.updateTable("state_all")
|
|
249
|
+
.set({ snapshot_content: { value: "hello world from version b UPDATED" } })
|
|
250
|
+
.where("entity_id", "=", "e0")
|
|
251
|
+
.where("schema_key", "=", "mock_schema")
|
|
252
|
+
.where("version_id", "=", "version_b")
|
|
253
|
+
.execute();
|
|
254
|
+
const stateAfterUpdate = await lix.db
|
|
255
|
+
.selectFrom("state_all")
|
|
256
|
+
.where("schema_key", "=", "mock_schema")
|
|
257
|
+
.where("entity_id", "=", "e0")
|
|
258
|
+
.selectAll()
|
|
259
|
+
.execute();
|
|
260
|
+
expect(stateAfterUpdate).toMatchObject([
|
|
261
|
+
{
|
|
262
|
+
entity_id: "e0",
|
|
263
|
+
file_id: "f0",
|
|
264
|
+
schema_key: "mock_schema",
|
|
265
|
+
plugin_key: "mock_plugin",
|
|
266
|
+
snapshot_content: {
|
|
267
|
+
value: "hello world from version a",
|
|
268
|
+
},
|
|
269
|
+
version_id: "version_a",
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
entity_id: "e0",
|
|
273
|
+
file_id: "f0",
|
|
274
|
+
schema_key: "mock_schema",
|
|
275
|
+
plugin_key: "mock_plugin",
|
|
276
|
+
snapshot_content: {
|
|
277
|
+
value: "hello world from version b UPDATED",
|
|
278
|
+
},
|
|
279
|
+
version_id: "version_b",
|
|
280
|
+
},
|
|
281
|
+
]);
|
|
282
|
+
await lix.db
|
|
283
|
+
.deleteFrom("state_all")
|
|
284
|
+
.where("entity_id", "=", "e0")
|
|
285
|
+
.where("version_id", "=", "version_b")
|
|
286
|
+
.execute();
|
|
287
|
+
const stateAfterDelete = await lix.db
|
|
288
|
+
.selectFrom("state_all")
|
|
289
|
+
.where("schema_key", "=", "mock_schema")
|
|
290
|
+
.where("entity_id", "=", "e0")
|
|
291
|
+
.selectAll()
|
|
292
|
+
.execute();
|
|
293
|
+
expect(stateAfterDelete).toMatchObject([
|
|
294
|
+
{
|
|
295
|
+
entity_id: "e0",
|
|
296
|
+
file_id: "f0",
|
|
297
|
+
schema_key: "mock_schema",
|
|
298
|
+
plugin_key: "mock_plugin",
|
|
299
|
+
snapshot_content: {
|
|
300
|
+
value: "hello world from version a",
|
|
301
|
+
},
|
|
302
|
+
version_id: "version_a",
|
|
303
|
+
},
|
|
304
|
+
]);
|
|
305
|
+
});
|
|
306
|
+
test("created_at and updated_at timestamps are computed correctly", async () => {
|
|
307
|
+
const lix = await openLix({});
|
|
308
|
+
const mockSchema = {
|
|
309
|
+
"x-lix-key": "mock_schema",
|
|
310
|
+
"x-lix-version": "1.0",
|
|
311
|
+
type: "object",
|
|
312
|
+
additionalProperties: false,
|
|
313
|
+
properties: {
|
|
314
|
+
value: {
|
|
315
|
+
type: "string",
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
await lix.db
|
|
320
|
+
.insertInto("stored_schema")
|
|
321
|
+
.values({ value: mockSchema })
|
|
322
|
+
.execute();
|
|
323
|
+
// Insert initial entity
|
|
324
|
+
await lix.db
|
|
325
|
+
.insertInto("state_all")
|
|
326
|
+
.values({
|
|
327
|
+
entity_id: "e0",
|
|
328
|
+
file_id: "f0",
|
|
329
|
+
schema_key: "mock_schema",
|
|
330
|
+
plugin_key: "lix_own_entity",
|
|
331
|
+
schema_version: "1.0",
|
|
332
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
333
|
+
snapshot_content: {
|
|
334
|
+
value: "initial value",
|
|
335
|
+
},
|
|
336
|
+
})
|
|
337
|
+
.execute();
|
|
338
|
+
const stateAfterInsert = await lix.db
|
|
339
|
+
.selectFrom("state_all")
|
|
340
|
+
.where("entity_id", "=", "e0")
|
|
341
|
+
.selectAll()
|
|
342
|
+
.execute();
|
|
343
|
+
expect(stateAfterInsert).toHaveLength(1);
|
|
344
|
+
expect(stateAfterInsert[0]?.created_at).toBeDefined();
|
|
345
|
+
expect(stateAfterInsert[0]?.updated_at).toBeDefined();
|
|
346
|
+
expect(stateAfterInsert[0]?.created_at).toBe(stateAfterInsert[0]?.updated_at);
|
|
347
|
+
// Wait a bit to ensure different timestamps
|
|
348
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
349
|
+
// Update the entity
|
|
350
|
+
await lix.db
|
|
351
|
+
.updateTable("state_all")
|
|
352
|
+
.set({
|
|
353
|
+
snapshot_content: {
|
|
354
|
+
value: "updated value",
|
|
355
|
+
},
|
|
356
|
+
})
|
|
357
|
+
.where("entity_id", "=", "e0")
|
|
358
|
+
.where("schema_key", "=", "mock_schema")
|
|
359
|
+
.execute();
|
|
360
|
+
const stateAfterUpdate = await lix.db
|
|
361
|
+
.selectFrom("state_all")
|
|
362
|
+
.where("entity_id", "=", "e0")
|
|
363
|
+
.selectAll()
|
|
364
|
+
.execute();
|
|
365
|
+
expect(stateAfterUpdate).toHaveLength(1);
|
|
366
|
+
expect(stateAfterUpdate[0]?.created_at).toBeDefined();
|
|
367
|
+
expect(stateAfterUpdate[0]?.updated_at).toBeDefined();
|
|
368
|
+
// created_at should remain the same
|
|
369
|
+
expect(stateAfterUpdate[0]?.created_at).toBe(stateAfterInsert[0]?.created_at);
|
|
370
|
+
// updated_at should be different (newer)
|
|
371
|
+
expect(stateAfterUpdate[0]?.updated_at).not.toBe(stateAfterInsert[0]?.updated_at);
|
|
372
|
+
expect(new Date(stateAfterUpdate[0].updated_at).getTime()).toBeGreaterThan(new Date(stateAfterInsert[0].updated_at).getTime());
|
|
373
|
+
});
|
|
374
|
+
test("created_at and updated_at are version specific", async () => {
|
|
375
|
+
const lix = await openLix({});
|
|
376
|
+
await createVersion({ lix, id: "version_a" });
|
|
377
|
+
await createVersion({ lix, id: "version_b" });
|
|
378
|
+
const mockSchema = {
|
|
379
|
+
"x-lix-key": "mock_schema",
|
|
380
|
+
"x-lix-version": "1.0",
|
|
381
|
+
additionalProperties: false,
|
|
382
|
+
type: "object",
|
|
383
|
+
properties: {
|
|
384
|
+
value: {
|
|
385
|
+
type: "string",
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
await lix.db
|
|
390
|
+
.insertInto("stored_schema")
|
|
391
|
+
.values({ value: mockSchema })
|
|
392
|
+
.execute();
|
|
393
|
+
// Insert entity in version A
|
|
394
|
+
await lix.db
|
|
395
|
+
.insertInto("state_all")
|
|
396
|
+
.values({
|
|
397
|
+
entity_id: "e0",
|
|
398
|
+
file_id: "f0",
|
|
399
|
+
schema_key: "mock_schema",
|
|
400
|
+
plugin_key: "lix_own_entity",
|
|
401
|
+
schema_version: "1.0",
|
|
402
|
+
version_id: "version_a",
|
|
403
|
+
snapshot_content: {
|
|
404
|
+
value: "value in version a",
|
|
405
|
+
},
|
|
406
|
+
})
|
|
407
|
+
.execute();
|
|
408
|
+
// Wait a bit to ensure different timestamps
|
|
409
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
410
|
+
// Insert same entity in version B
|
|
411
|
+
await lix.db
|
|
412
|
+
.insertInto("state_all")
|
|
413
|
+
.values({
|
|
414
|
+
entity_id: "e0",
|
|
415
|
+
file_id: "f0",
|
|
416
|
+
schema_key: "mock_schema",
|
|
417
|
+
plugin_key: "lix_own_entity",
|
|
418
|
+
schema_version: "1.0",
|
|
419
|
+
version_id: "version_b",
|
|
420
|
+
snapshot_content: {
|
|
421
|
+
value: "value in version b",
|
|
422
|
+
},
|
|
423
|
+
})
|
|
424
|
+
.execute();
|
|
425
|
+
const stateVersionA = await lix.db
|
|
426
|
+
.selectFrom("state_all")
|
|
427
|
+
.where("entity_id", "=", "e0")
|
|
428
|
+
.where("version_id", "=", "version_a")
|
|
429
|
+
.selectAll()
|
|
430
|
+
.execute();
|
|
431
|
+
const stateVersionB = await lix.db
|
|
432
|
+
.selectFrom("state_all")
|
|
433
|
+
.where("entity_id", "=", "e0")
|
|
434
|
+
.where("version_id", "=", "version_b")
|
|
435
|
+
.selectAll()
|
|
436
|
+
.execute();
|
|
437
|
+
expect(stateVersionA).toHaveLength(1);
|
|
438
|
+
expect(stateVersionB).toHaveLength(1);
|
|
439
|
+
// Both should have timestamps
|
|
440
|
+
expect(stateVersionA[0]?.created_at).toBeDefined();
|
|
441
|
+
expect(stateVersionA[0]?.updated_at).toBeDefined();
|
|
442
|
+
expect(stateVersionB[0]?.created_at).toBeDefined();
|
|
443
|
+
expect(stateVersionB[0]?.updated_at).toBeDefined();
|
|
444
|
+
// the same entity has been inserted but with different changes
|
|
445
|
+
expect(stateVersionA[0]?.created_at).not.toBe(stateVersionB[0]?.created_at);
|
|
446
|
+
// Wait and update only version B
|
|
447
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
448
|
+
await lix.db
|
|
449
|
+
.updateTable("state_all")
|
|
450
|
+
.set({
|
|
451
|
+
snapshot_content: {
|
|
452
|
+
value: "updated value in version b",
|
|
453
|
+
},
|
|
454
|
+
})
|
|
455
|
+
.where("entity_id", "=", "e0")
|
|
456
|
+
.where("version_id", "=", "version_b")
|
|
457
|
+
.execute();
|
|
458
|
+
const updatedStateVersionA = await lix.db
|
|
459
|
+
.selectFrom("state_all")
|
|
460
|
+
.where("entity_id", "=", "e0")
|
|
461
|
+
.where("version_id", "=", "version_a")
|
|
462
|
+
.selectAll()
|
|
463
|
+
.execute();
|
|
464
|
+
const updatedStateVersionB = await lix.db
|
|
465
|
+
.selectFrom("state_all")
|
|
466
|
+
.where("entity_id", "=", "e0")
|
|
467
|
+
.where("version_id", "=", "version_b")
|
|
468
|
+
.selectAll()
|
|
469
|
+
.execute();
|
|
470
|
+
// Version A should remain unchanged
|
|
471
|
+
expect(updatedStateVersionA[0]?.updated_at).toBe(stateVersionA[0]?.updated_at);
|
|
472
|
+
// Version B should have updated timestamp
|
|
473
|
+
expect(updatedStateVersionB[0]?.updated_at).not.toBe(stateVersionB[0]?.updated_at);
|
|
474
|
+
expect(new Date(updatedStateVersionB[0].updated_at).getTime()).toBeGreaterThan(new Date(stateVersionB[0].updated_at).getTime());
|
|
475
|
+
});
|
|
476
|
+
test("state appears in both versions when they share the same change set", async () => {
|
|
477
|
+
const lix = await openLix({});
|
|
478
|
+
const versionA = await createVersion({ lix, id: "version_a" });
|
|
479
|
+
// Insert state into version A
|
|
480
|
+
await lix.db
|
|
481
|
+
.insertInto("state_all")
|
|
482
|
+
.values({
|
|
483
|
+
entity_id: "e0",
|
|
484
|
+
file_id: "f0",
|
|
485
|
+
schema_key: "mock_schema",
|
|
486
|
+
plugin_key: "mock_plugin",
|
|
487
|
+
schema_version: "1.0",
|
|
488
|
+
snapshot_content: {
|
|
489
|
+
value: "shared state",
|
|
490
|
+
},
|
|
491
|
+
version_id: "version_a",
|
|
492
|
+
})
|
|
493
|
+
.execute();
|
|
494
|
+
const versionAAfterInsert = await lix.db
|
|
495
|
+
.selectFrom("version")
|
|
496
|
+
.where("id", "=", versionA.id)
|
|
497
|
+
.selectAll()
|
|
498
|
+
.executeTakeFirstOrThrow();
|
|
499
|
+
// Create version B with the same change set as version A
|
|
500
|
+
await createVersion({
|
|
501
|
+
lix,
|
|
502
|
+
id: "version_b",
|
|
503
|
+
changeSet: { id: versionAAfterInsert.change_set_id },
|
|
504
|
+
});
|
|
505
|
+
const stateInBothVersions = await lix.db
|
|
506
|
+
.selectFrom("state_all")
|
|
507
|
+
.where("schema_key", "=", "mock_schema")
|
|
508
|
+
.where("entity_id", "=", "e0")
|
|
509
|
+
.selectAll()
|
|
510
|
+
.execute();
|
|
511
|
+
// Both versions should see the same state
|
|
512
|
+
expect(stateInBothVersions).toMatchObject([
|
|
513
|
+
{
|
|
514
|
+
entity_id: "e0",
|
|
515
|
+
schema_key: "mock_schema",
|
|
516
|
+
snapshot_content: { value: "shared state" },
|
|
517
|
+
version_id: "version_a",
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
entity_id: "e0",
|
|
521
|
+
schema_key: "mock_schema",
|
|
522
|
+
snapshot_content: { value: "shared state" },
|
|
523
|
+
version_id: "version_b",
|
|
524
|
+
},
|
|
525
|
+
]);
|
|
526
|
+
});
|
|
527
|
+
test("state diverges when versions have common ancestor but different changes", async () => {
|
|
528
|
+
const lix = await openLix({});
|
|
529
|
+
// Create base version and add initial state
|
|
530
|
+
const baseVersion = await createVersion({ lix, id: "base_version" });
|
|
531
|
+
await lix.db
|
|
532
|
+
.insertInto("state_all")
|
|
533
|
+
.values({
|
|
534
|
+
entity_id: "e0",
|
|
535
|
+
file_id: "f0",
|
|
536
|
+
schema_key: "mock_schema",
|
|
537
|
+
plugin_key: "mock_plugin",
|
|
538
|
+
schema_version: "1.0",
|
|
539
|
+
snapshot_content: {
|
|
540
|
+
value: "base state",
|
|
541
|
+
},
|
|
542
|
+
version_id: "base_version",
|
|
543
|
+
})
|
|
544
|
+
.execute();
|
|
545
|
+
const baseVersionAfterInsert = await lix.db
|
|
546
|
+
.selectFrom("version")
|
|
547
|
+
.where("id", "=", baseVersion.id)
|
|
548
|
+
.selectAll()
|
|
549
|
+
.executeTakeFirstOrThrow();
|
|
550
|
+
// Create two versions from the same base changeset
|
|
551
|
+
await createVersion({
|
|
552
|
+
lix,
|
|
553
|
+
id: "version_a",
|
|
554
|
+
changeSet: { id: baseVersionAfterInsert.change_set_id },
|
|
555
|
+
});
|
|
556
|
+
await createVersion({
|
|
557
|
+
lix,
|
|
558
|
+
id: "version_b",
|
|
559
|
+
changeSet: { id: baseVersionAfterInsert.change_set_id },
|
|
560
|
+
});
|
|
561
|
+
const versions = await lix.db
|
|
562
|
+
.selectFrom("version")
|
|
563
|
+
.where("id", "in", ["base_version", "version_a", "version_b"])
|
|
564
|
+
.select(["id", "change_set_id"])
|
|
565
|
+
.execute();
|
|
566
|
+
expect(versions).toHaveLength(3);
|
|
567
|
+
// Both versions should initially see the base state
|
|
568
|
+
const initialState = await lix.db
|
|
569
|
+
.selectFrom("state_all")
|
|
570
|
+
.where("schema_key", "=", "mock_schema")
|
|
571
|
+
.where("entity_id", "=", "e0")
|
|
572
|
+
.selectAll()
|
|
573
|
+
.execute();
|
|
574
|
+
expect(initialState).toHaveLength(3); // base, version_a, version_b
|
|
575
|
+
// Update state in version A
|
|
576
|
+
await lix.db
|
|
577
|
+
.updateTable("state_all")
|
|
578
|
+
.set({
|
|
579
|
+
snapshot_content: { value: "updated in version A" },
|
|
580
|
+
})
|
|
581
|
+
.where("entity_id", "=", "e0")
|
|
582
|
+
.where("version_id", "=", "version_a")
|
|
583
|
+
.execute();
|
|
584
|
+
// Update state in version B differently
|
|
585
|
+
await lix.db
|
|
586
|
+
.updateTable("state_all")
|
|
587
|
+
.set({
|
|
588
|
+
snapshot_content: { value: "updated in version B" },
|
|
589
|
+
})
|
|
590
|
+
.where("entity_id", "=", "e0")
|
|
591
|
+
.where("version_id", "=", "version_b")
|
|
592
|
+
.execute();
|
|
593
|
+
const divergedState = await lix.db
|
|
594
|
+
.selectFrom("state_all")
|
|
595
|
+
.where("schema_key", "=", "mock_schema")
|
|
596
|
+
.where("entity_id", "=", "e0")
|
|
597
|
+
.selectAll()
|
|
598
|
+
.execute();
|
|
599
|
+
// All three versions should have different states
|
|
600
|
+
expect(divergedState).toMatchObject([
|
|
601
|
+
{
|
|
602
|
+
entity_id: "e0",
|
|
603
|
+
snapshot_content: { value: "base state" },
|
|
604
|
+
version_id: "base_version",
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
entity_id: "e0",
|
|
608
|
+
snapshot_content: { value: "updated in version A" },
|
|
609
|
+
version_id: "version_a",
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
entity_id: "e0",
|
|
613
|
+
snapshot_content: { value: "updated in version B" },
|
|
614
|
+
version_id: "version_b",
|
|
615
|
+
},
|
|
616
|
+
]);
|
|
617
|
+
});
|
|
618
|
+
// Write-through cache behavior tests
|
|
619
|
+
test("write-through cache: insert operations populate cache immediately", async () => {
|
|
620
|
+
const lix = await openLix({});
|
|
621
|
+
const activeVersion = await lix.db
|
|
622
|
+
.selectFrom("active_version")
|
|
623
|
+
.innerJoin("version", "active_version.version_id", "version.id")
|
|
624
|
+
.selectAll("version")
|
|
625
|
+
.executeTakeFirstOrThrow();
|
|
626
|
+
// Insert state data - should populate cache via write-through
|
|
627
|
+
await lix.db
|
|
628
|
+
.insertInto("state_all")
|
|
629
|
+
.values({
|
|
630
|
+
entity_id: "write-through-entity",
|
|
631
|
+
schema_key: "write-through-schema",
|
|
632
|
+
file_id: "write-through-file",
|
|
633
|
+
plugin_key: "write-through-plugin",
|
|
634
|
+
snapshot_content: { test: "write-through-data" },
|
|
635
|
+
schema_version: "1.0",
|
|
636
|
+
version_id: activeVersion.id,
|
|
637
|
+
})
|
|
638
|
+
.execute();
|
|
639
|
+
// Cache should be populated immediately via write-through
|
|
640
|
+
const cacheEntry = await lix.db
|
|
641
|
+
.selectFrom("internal_state_cache")
|
|
642
|
+
.where("entity_id", "=", "write-through-entity")
|
|
643
|
+
.where("schema_key", "=", "write-through-schema")
|
|
644
|
+
.where("file_id", "=", "write-through-file")
|
|
645
|
+
.where("version_id", "=", activeVersion.id)
|
|
646
|
+
.selectAll()
|
|
647
|
+
.executeTakeFirst();
|
|
648
|
+
expect(cacheEntry).toBeDefined();
|
|
649
|
+
expect(cacheEntry?.entity_id).toBe("write-through-entity");
|
|
650
|
+
expect(cacheEntry?.plugin_key).toBe("write-through-plugin");
|
|
651
|
+
expect(cacheEntry?.snapshot_content).toEqual({
|
|
652
|
+
test: "write-through-data",
|
|
653
|
+
});
|
|
654
|
+
// State view should return the same data (from cache)
|
|
655
|
+
const stateResults = await lix.db
|
|
656
|
+
.selectFrom("state_all")
|
|
657
|
+
.where("entity_id", "=", "write-through-entity")
|
|
658
|
+
.selectAll()
|
|
659
|
+
.execute();
|
|
660
|
+
expect(stateResults).toHaveLength(1);
|
|
661
|
+
expect(stateResults[0]?.entity_id).toBe("write-through-entity");
|
|
662
|
+
expect(stateResults[0]?.snapshot_content).toEqual({
|
|
663
|
+
test: "write-through-data",
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
test("write-through cache: update operations update cache immediately", async () => {
|
|
667
|
+
const lix = await openLix({});
|
|
668
|
+
const activeVersion = await lix.db
|
|
669
|
+
.selectFrom("active_version")
|
|
670
|
+
.innerJoin("version", "active_version.version_id", "version.id")
|
|
671
|
+
.selectAll("version")
|
|
672
|
+
.executeTakeFirstOrThrow();
|
|
673
|
+
// Insert initial state
|
|
674
|
+
await lix.db
|
|
675
|
+
.insertInto("state_all")
|
|
676
|
+
.values({
|
|
677
|
+
entity_id: "update-cache-entity",
|
|
678
|
+
schema_key: "update-cache-schema",
|
|
679
|
+
file_id: "update-cache-file",
|
|
680
|
+
plugin_key: "initial-plugin",
|
|
681
|
+
snapshot_content: { initial: "value" },
|
|
682
|
+
schema_version: "1.0",
|
|
683
|
+
version_id: activeVersion.id,
|
|
684
|
+
})
|
|
685
|
+
.execute();
|
|
686
|
+
// Update the state - should update cache via write-through
|
|
687
|
+
await lix.db
|
|
688
|
+
.updateTable("state_all")
|
|
689
|
+
.set({
|
|
690
|
+
snapshot_content: { updated: "value" },
|
|
691
|
+
plugin_key: "updated-plugin",
|
|
692
|
+
})
|
|
693
|
+
.where("entity_id", "=", "update-cache-entity")
|
|
694
|
+
.where("schema_key", "=", "update-cache-schema")
|
|
695
|
+
.where("file_id", "=", "update-cache-file")
|
|
696
|
+
.where("version_id", "=", activeVersion.id)
|
|
697
|
+
.execute();
|
|
698
|
+
// Cache should be immediately updated
|
|
699
|
+
const cacheEntry = await lix.db
|
|
700
|
+
.selectFrom("internal_state_cache")
|
|
701
|
+
.where("entity_id", "=", "update-cache-entity")
|
|
702
|
+
.where("schema_key", "=", "update-cache-schema")
|
|
703
|
+
.where("file_id", "=", "update-cache-file")
|
|
704
|
+
.where("version_id", "=", activeVersion.id)
|
|
705
|
+
.selectAll()
|
|
706
|
+
.executeTakeFirst();
|
|
707
|
+
expect(cacheEntry).toBeDefined();
|
|
708
|
+
expect(cacheEntry?.snapshot_content).toEqual({
|
|
709
|
+
updated: "value",
|
|
710
|
+
});
|
|
711
|
+
expect(cacheEntry?.plugin_key).toBe("updated-plugin");
|
|
712
|
+
// State view should return updated data
|
|
713
|
+
const stateResults = await lix.db
|
|
714
|
+
.selectFrom("state_all")
|
|
715
|
+
.where("entity_id", "=", "update-cache-entity")
|
|
716
|
+
.selectAll()
|
|
717
|
+
.execute();
|
|
718
|
+
expect(stateResults).toHaveLength(1);
|
|
719
|
+
expect(stateResults[0]?.snapshot_content).toEqual({ updated: "value" });
|
|
720
|
+
expect(stateResults[0]?.plugin_key).toBe("updated-plugin");
|
|
721
|
+
});
|
|
722
|
+
test("delete operations remove entries from underlying data", async () => {
|
|
723
|
+
const lix = await openLix({});
|
|
724
|
+
const activeVersion = await lix.db
|
|
725
|
+
.selectFrom("active_version")
|
|
726
|
+
.innerJoin("version", "active_version.version_id", "version.id")
|
|
727
|
+
.selectAll("version")
|
|
728
|
+
.executeTakeFirstOrThrow();
|
|
729
|
+
// Insert initial state
|
|
730
|
+
await lix.db
|
|
731
|
+
.insertInto("state_all")
|
|
732
|
+
.values({
|
|
733
|
+
entity_id: "delete-cache-entity",
|
|
734
|
+
schema_key: "delete-cache-schema",
|
|
735
|
+
file_id: "delete-cache-file",
|
|
736
|
+
plugin_key: "delete-plugin",
|
|
737
|
+
snapshot_content: { to: "delete" },
|
|
738
|
+
schema_version: "1.0",
|
|
739
|
+
version_id: activeVersion.id,
|
|
740
|
+
})
|
|
741
|
+
.execute();
|
|
742
|
+
// Verify data exists
|
|
743
|
+
const beforeDelete = await lix.db
|
|
744
|
+
.selectFrom("state_all")
|
|
745
|
+
.where("entity_id", "=", "delete-cache-entity")
|
|
746
|
+
.selectAll()
|
|
747
|
+
.execute();
|
|
748
|
+
expect(beforeDelete).toHaveLength(1);
|
|
749
|
+
// Delete the state - this creates a deletion change (doesn't physically remove cache entry)
|
|
750
|
+
await lix.db
|
|
751
|
+
.deleteFrom("state_all")
|
|
752
|
+
.where("entity_id", "=", "delete-cache-entity")
|
|
753
|
+
.where("schema_key", "=", "delete-cache-schema")
|
|
754
|
+
.where("file_id", "=", "delete-cache-file")
|
|
755
|
+
.where("version_id", "=", activeVersion.id)
|
|
756
|
+
.execute();
|
|
757
|
+
// Data should no longer be accessible through state view
|
|
758
|
+
const afterDelete = await lix.db
|
|
759
|
+
.selectFrom("state_all")
|
|
760
|
+
.where("entity_id", "=", "delete-cache-entity")
|
|
761
|
+
.selectAll()
|
|
762
|
+
.execute();
|
|
763
|
+
expect(afterDelete).toHaveLength(0);
|
|
764
|
+
});
|
|
765
|
+
test("change.created_at and state timestamps are consistent", async () => {
|
|
766
|
+
const lix = await openLix({});
|
|
767
|
+
const mockSchema = {
|
|
768
|
+
"x-lix-key": "mock_schema",
|
|
769
|
+
"x-lix-version": "1.0",
|
|
770
|
+
type: "object",
|
|
771
|
+
additionalProperties: false,
|
|
772
|
+
properties: {
|
|
773
|
+
value: {
|
|
774
|
+
type: "string",
|
|
775
|
+
},
|
|
776
|
+
},
|
|
777
|
+
};
|
|
778
|
+
await lix.db
|
|
779
|
+
.insertInto("stored_schema")
|
|
780
|
+
.values({ value: mockSchema })
|
|
781
|
+
.execute();
|
|
782
|
+
// Insert state data
|
|
783
|
+
await lix.db
|
|
784
|
+
.insertInto("state_all")
|
|
785
|
+
.values({
|
|
786
|
+
entity_id: "timestamp-test-entity",
|
|
787
|
+
schema_key: "mock_schema",
|
|
788
|
+
file_id: "timestamp-test-file",
|
|
789
|
+
plugin_key: "timestamp-test-plugin",
|
|
790
|
+
snapshot_content: { value: "timestamp test" },
|
|
791
|
+
schema_version: "1.0",
|
|
792
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
793
|
+
})
|
|
794
|
+
.execute();
|
|
795
|
+
// Get the change record
|
|
796
|
+
const changeRecord = await lix.db
|
|
797
|
+
.selectFrom("internal_change")
|
|
798
|
+
.where("entity_id", "=", "timestamp-test-entity")
|
|
799
|
+
.where("schema_key", "=", "mock_schema")
|
|
800
|
+
.select(["created_at"])
|
|
801
|
+
.executeTakeFirstOrThrow();
|
|
802
|
+
// Get the state cache record
|
|
803
|
+
const cacheRecord = await lix.db
|
|
804
|
+
.selectFrom("internal_state_cache")
|
|
805
|
+
.where("entity_id", "=", "timestamp-test-entity")
|
|
806
|
+
.where("schema_key", "=", "mock_schema")
|
|
807
|
+
.select(["created_at", "updated_at"])
|
|
808
|
+
.executeTakeFirstOrThrow();
|
|
809
|
+
// Verify all timestamps are identical
|
|
810
|
+
expect(changeRecord.created_at).toBe(cacheRecord.created_at);
|
|
811
|
+
expect(changeRecord.created_at).toBe(cacheRecord.updated_at);
|
|
812
|
+
});
|
|
813
|
+
test("state and state_all views expose change_id for blame and diff functionality", async () => {
|
|
814
|
+
const lix = await openLix({});
|
|
815
|
+
const mockSchema = {
|
|
816
|
+
"x-lix-key": "mock_schema",
|
|
817
|
+
"x-lix-version": "1.0",
|
|
818
|
+
type: "object",
|
|
819
|
+
additionalProperties: false,
|
|
820
|
+
properties: {
|
|
821
|
+
value: {
|
|
822
|
+
type: "string",
|
|
823
|
+
},
|
|
824
|
+
},
|
|
825
|
+
};
|
|
826
|
+
await lix.db
|
|
827
|
+
.insertInto("stored_schema")
|
|
828
|
+
.values({ value: mockSchema })
|
|
829
|
+
.execute();
|
|
830
|
+
// Insert initial state using Kysely to ensure virtual table is triggered
|
|
831
|
+
await lix.db
|
|
832
|
+
.insertInto("state_all")
|
|
833
|
+
.values({
|
|
834
|
+
entity_id: "change-id-test-entity",
|
|
835
|
+
schema_key: "mock_schema",
|
|
836
|
+
file_id: "change-id-test-file",
|
|
837
|
+
plugin_key: "change-id-test-plugin",
|
|
838
|
+
snapshot_content: { value: "initial value" },
|
|
839
|
+
schema_version: "1.0",
|
|
840
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
841
|
+
})
|
|
842
|
+
.execute();
|
|
843
|
+
// Query state_all view to verify change_id is exposed
|
|
844
|
+
const stateAllResult = await lix.db
|
|
845
|
+
.selectFrom("state_all")
|
|
846
|
+
.where("entity_id", "=", "change-id-test-entity")
|
|
847
|
+
.where("schema_key", "=", "mock_schema")
|
|
848
|
+
.selectAll()
|
|
849
|
+
.execute();
|
|
850
|
+
expect(stateAllResult).toHaveLength(1);
|
|
851
|
+
expect(stateAllResult[0]?.change_id).toBeDefined();
|
|
852
|
+
expect(typeof stateAllResult[0]?.change_id).toBe("string");
|
|
853
|
+
// Query state view (filtered by active version) to verify change_id is exposed
|
|
854
|
+
const stateResult = await lix.db
|
|
855
|
+
.selectFrom("state")
|
|
856
|
+
.where("entity_id", "=", "change-id-test-entity")
|
|
857
|
+
.where("schema_key", "=", "mock_schema")
|
|
858
|
+
.selectAll()
|
|
859
|
+
.execute();
|
|
860
|
+
expect(stateResult).toHaveLength(1);
|
|
861
|
+
expect(stateResult[0]?.change_id).toBeDefined();
|
|
862
|
+
expect(typeof stateResult[0]?.change_id).toBe("string");
|
|
863
|
+
// Verify that change_id matches between state and state_all views
|
|
864
|
+
expect(stateResult[0]?.change_id).toBe(stateAllResult[0]?.change_id);
|
|
865
|
+
// Get the actual change record to verify the change_id is correct
|
|
866
|
+
const changeRecord = await lix.db
|
|
867
|
+
.selectFrom("change")
|
|
868
|
+
.where("entity_id", "=", "change-id-test-entity")
|
|
869
|
+
.where("schema_key", "=", "mock_schema")
|
|
870
|
+
.select(["change.id", "snapshot_content"])
|
|
871
|
+
.executeTakeFirstOrThrow();
|
|
872
|
+
// Verify that the change_id in the views matches the actual change.id
|
|
873
|
+
expect(stateResult[0]?.change_id).toBe(changeRecord.id);
|
|
874
|
+
expect(stateAllResult[0]?.change_id).toBe(changeRecord.id);
|
|
875
|
+
// Verify that the snapshot content in the change matches the state view
|
|
876
|
+
expect(changeRecord.snapshot_content).toEqual({ value: "initial value" });
|
|
877
|
+
expect(stateResult[0]?.snapshot_content).toEqual({ value: "initial value" });
|
|
878
|
+
// Update the entity to create a new change
|
|
879
|
+
await lix.db
|
|
880
|
+
.updateTable("state_all")
|
|
881
|
+
.set({
|
|
882
|
+
snapshot_content: { value: "updated value" },
|
|
883
|
+
})
|
|
884
|
+
.where("entity_id", "=", "change-id-test-entity")
|
|
885
|
+
.where("schema_key", "=", "mock_schema")
|
|
886
|
+
.execute();
|
|
887
|
+
// Query again to verify change_id updated after modification
|
|
888
|
+
const updatedStateResult = await lix.db
|
|
889
|
+
.selectFrom("state_all")
|
|
890
|
+
.where("entity_id", "=", "change-id-test-entity")
|
|
891
|
+
.where("schema_key", "=", "mock_schema")
|
|
892
|
+
.selectAll()
|
|
893
|
+
.execute();
|
|
894
|
+
expect(updatedStateResult).toHaveLength(1);
|
|
895
|
+
expect(updatedStateResult[0]?.change_id).toBeDefined();
|
|
896
|
+
// The change_id should be different after the update (new change created)
|
|
897
|
+
expect(updatedStateResult[0]?.change_id).not.toBe(stateResult[0]?.change_id);
|
|
898
|
+
// Get the new change record
|
|
899
|
+
const newChangeRecord = await lix.db
|
|
900
|
+
.selectFrom("change")
|
|
901
|
+
.where("entity_id", "=", "change-id-test-entity")
|
|
902
|
+
.where("schema_key", "=", "mock_schema")
|
|
903
|
+
.orderBy("created_at", "desc")
|
|
904
|
+
.select(["change.id", "snapshot_content"])
|
|
905
|
+
.executeTakeFirstOrThrow();
|
|
906
|
+
// Verify the new change_id matches the latest change
|
|
907
|
+
expect(updatedStateResult[0]?.change_id).toBe(newChangeRecord.id);
|
|
908
|
+
// Verify that the updated snapshot content in the change matches the state view
|
|
909
|
+
expect(newChangeRecord.snapshot_content).toEqual({ value: "updated value" });
|
|
910
|
+
expect(updatedStateResult[0]?.snapshot_content).toEqual({
|
|
911
|
+
value: "updated value",
|
|
912
|
+
});
|
|
913
|
+
});
|
|
914
|
+
// Important to note that only a full cache clear (like during schema changes) triggers
|
|
915
|
+
// a cache miss and repopulation from the CTE at the moment!
|
|
916
|
+
//
|
|
917
|
+
// This is simpler, at the cost of state inconsistencies when changes are made
|
|
918
|
+
// without populating or invalidating the cache.
|
|
919
|
+
test.todo("state view should work and re-populate the cache after cache is fully (!) cleared", async () => {
|
|
920
|
+
const lix = await openLix({});
|
|
921
|
+
// Insert a key-value pair
|
|
922
|
+
await lix.db
|
|
923
|
+
.insertInto("key_value")
|
|
924
|
+
.values({
|
|
925
|
+
key: "test_cache_miss",
|
|
926
|
+
value: "initial_value",
|
|
927
|
+
})
|
|
928
|
+
.execute();
|
|
929
|
+
// Verify it's accessible through state view (should populate cache)
|
|
930
|
+
const stateBeforeCacheClear = await lix.db
|
|
931
|
+
.selectFrom("state_all")
|
|
932
|
+
.where("schema_key", "=", "lix_key_value")
|
|
933
|
+
.where("entity_id", "=", "test_cache_miss")
|
|
934
|
+
.selectAll()
|
|
935
|
+
.execute();
|
|
936
|
+
expect(stateBeforeCacheClear).toHaveLength(1);
|
|
937
|
+
expect(stateBeforeCacheClear[0]).toMatchObject({
|
|
938
|
+
entity_id: "test_cache_miss",
|
|
939
|
+
schema_key: "lix_key_value",
|
|
940
|
+
snapshot_content: {
|
|
941
|
+
key: "test_cache_miss",
|
|
942
|
+
value: "initial_value",
|
|
943
|
+
},
|
|
944
|
+
});
|
|
945
|
+
// Verify it's in the cache
|
|
946
|
+
const cacheBeforeClear = await lix.db
|
|
947
|
+
.selectFrom("internal_state_cache")
|
|
948
|
+
.where("schema_key", "=", "lix_key_value")
|
|
949
|
+
.where("entity_id", "=", "test_cache_miss")
|
|
950
|
+
.selectAll()
|
|
951
|
+
.execute();
|
|
952
|
+
expect(cacheBeforeClear).toHaveLength(1);
|
|
953
|
+
// Simulate cache invalidation (like what happens during stored_schema insertion)
|
|
954
|
+
await lix.db
|
|
955
|
+
.deleteFrom("internal_state_cache")
|
|
956
|
+
.execute();
|
|
957
|
+
// Verify cache is empty
|
|
958
|
+
const cacheAfterClear = await lix.db
|
|
959
|
+
.selectFrom("internal_state_cache")
|
|
960
|
+
.selectAll()
|
|
961
|
+
.execute();
|
|
962
|
+
expect(cacheAfterClear).toHaveLength(0);
|
|
963
|
+
// Try to access the same data through state view again
|
|
964
|
+
// This should trigger cache miss logic and repopulate from CTE
|
|
965
|
+
const stateAfterCacheClear = await lix.db
|
|
966
|
+
.selectFrom("state_all")
|
|
967
|
+
.where("schema_key", "=", "lix_key_value")
|
|
968
|
+
.where("entity_id", "=", "test_cache_miss")
|
|
969
|
+
.selectAll()
|
|
970
|
+
.execute();
|
|
971
|
+
// This should work - if cache miss logic is working correctly
|
|
972
|
+
expect(stateAfterCacheClear).toHaveLength(1);
|
|
973
|
+
expect(stateAfterCacheClear[0]).toMatchObject({
|
|
974
|
+
entity_id: "test_cache_miss",
|
|
975
|
+
schema_key: "lix_key_value",
|
|
976
|
+
snapshot_content: {
|
|
977
|
+
key: "test_cache_miss",
|
|
978
|
+
value: "initial_value",
|
|
979
|
+
},
|
|
980
|
+
});
|
|
981
|
+
// Verify cache was repopulated
|
|
982
|
+
const cacheAfterRefill = await lix.db
|
|
983
|
+
.selectFrom("internal_state_cache")
|
|
984
|
+
.where("schema_key", "=", "lix_key_value")
|
|
985
|
+
.where("entity_id", "=", "test_cache_miss")
|
|
986
|
+
.selectAll()
|
|
987
|
+
.execute();
|
|
988
|
+
expect(cacheAfterRefill).toHaveLength(1);
|
|
989
|
+
});
|
|
990
|
+
test("delete operations are validated for foreign key constraints", async () => {
|
|
991
|
+
const lix = await openLix({});
|
|
992
|
+
// Define parent schema (referenced entity)
|
|
993
|
+
const parentSchema = {
|
|
994
|
+
"x-lix-key": "parent_entity",
|
|
995
|
+
"x-lix-version": "1.0",
|
|
996
|
+
"x-lix-primary-key": ["id"],
|
|
997
|
+
type: "object",
|
|
998
|
+
properties: {
|
|
999
|
+
id: { type: "string" },
|
|
1000
|
+
name: { type: "string" },
|
|
1001
|
+
},
|
|
1002
|
+
required: ["id", "name"],
|
|
1003
|
+
additionalProperties: false,
|
|
1004
|
+
};
|
|
1005
|
+
// Define child schema with foreign key to parent
|
|
1006
|
+
const childSchema = {
|
|
1007
|
+
"x-lix-key": "child_entity",
|
|
1008
|
+
"x-lix-version": "1.0",
|
|
1009
|
+
"x-lix-primary-key": ["id"],
|
|
1010
|
+
"x-lix-foreign-keys": {
|
|
1011
|
+
parent_id: {
|
|
1012
|
+
schemaKey: "parent_entity",
|
|
1013
|
+
property: "id",
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
type: "object",
|
|
1017
|
+
properties: {
|
|
1018
|
+
id: { type: "string" },
|
|
1019
|
+
parent_id: { type: "string" },
|
|
1020
|
+
value: { type: "string" },
|
|
1021
|
+
},
|
|
1022
|
+
required: ["id", "parent_id", "value"],
|
|
1023
|
+
additionalProperties: false,
|
|
1024
|
+
};
|
|
1025
|
+
// Register both schemas
|
|
1026
|
+
await lix.db
|
|
1027
|
+
.insertInto("stored_schema")
|
|
1028
|
+
.values([{ value: parentSchema }, { value: childSchema }])
|
|
1029
|
+
.execute();
|
|
1030
|
+
// Insert parent entity
|
|
1031
|
+
await lix.db
|
|
1032
|
+
.insertInto("state_all")
|
|
1033
|
+
.values({
|
|
1034
|
+
entity_id: "parent-1",
|
|
1035
|
+
schema_key: "parent_entity",
|
|
1036
|
+
file_id: "test-file",
|
|
1037
|
+
plugin_key: "test-plugin",
|
|
1038
|
+
snapshot_content: {
|
|
1039
|
+
id: "parent-1",
|
|
1040
|
+
name: "Parent Entity",
|
|
1041
|
+
},
|
|
1042
|
+
schema_version: "1.0",
|
|
1043
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1044
|
+
})
|
|
1045
|
+
.execute();
|
|
1046
|
+
// Insert child entity that references the parent
|
|
1047
|
+
await lix.db
|
|
1048
|
+
.insertInto("state_all")
|
|
1049
|
+
.values({
|
|
1050
|
+
entity_id: "child-1",
|
|
1051
|
+
schema_key: "child_entity",
|
|
1052
|
+
file_id: "test-file",
|
|
1053
|
+
plugin_key: "test-plugin",
|
|
1054
|
+
snapshot_content: {
|
|
1055
|
+
id: "child-1",
|
|
1056
|
+
parent_id: "parent-1",
|
|
1057
|
+
value: "Child Value",
|
|
1058
|
+
},
|
|
1059
|
+
schema_version: "1.0",
|
|
1060
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1061
|
+
})
|
|
1062
|
+
.execute();
|
|
1063
|
+
// Verify both entities exist
|
|
1064
|
+
const parentBefore = await lix.db
|
|
1065
|
+
.selectFrom("state_all")
|
|
1066
|
+
.where("entity_id", "=", "parent-1")
|
|
1067
|
+
.where("schema_key", "=", "parent_entity")
|
|
1068
|
+
.selectAll()
|
|
1069
|
+
.execute();
|
|
1070
|
+
const childBefore = await lix.db
|
|
1071
|
+
.selectFrom("state_all")
|
|
1072
|
+
.where("entity_id", "=", "child-1")
|
|
1073
|
+
.where("schema_key", "=", "child_entity")
|
|
1074
|
+
.selectAll()
|
|
1075
|
+
.execute();
|
|
1076
|
+
expect(parentBefore).toHaveLength(1);
|
|
1077
|
+
expect(childBefore).toHaveLength(1);
|
|
1078
|
+
// Attempting to delete the parent entity should fail due to foreign key constraint
|
|
1079
|
+
// because there's a child entity that references it
|
|
1080
|
+
await expect(lix.db
|
|
1081
|
+
.deleteFrom("state_all")
|
|
1082
|
+
.where("entity_id", "=", "parent-1")
|
|
1083
|
+
.where("schema_key", "=", "parent_entity")
|
|
1084
|
+
.execute()).rejects.toThrow(/foreign key/i);
|
|
1085
|
+
// Verify the parent still exists after failed deletion attempt
|
|
1086
|
+
const parentAfter = await lix.db
|
|
1087
|
+
.selectFrom("state_all")
|
|
1088
|
+
.where("entity_id", "=", "parent-1")
|
|
1089
|
+
.where("schema_key", "=", "parent_entity")
|
|
1090
|
+
.selectAll()
|
|
1091
|
+
.execute();
|
|
1092
|
+
expect(parentAfter).toHaveLength(1);
|
|
1093
|
+
});
|
|
1094
|
+
describe.each([
|
|
1095
|
+
{ scenario: "cache hit", clearCache: false },
|
|
1096
|
+
// { scenario: "cache miss", clearCache: true },
|
|
1097
|
+
])("($scenario) inheritance should work - child version should see entities from parent version", ({ clearCache }) => {
|
|
1098
|
+
test("child version inherits entities from parent version", async () => {
|
|
1099
|
+
const lix = await openLix({});
|
|
1100
|
+
// Insert an entity into global version
|
|
1101
|
+
await lix.db
|
|
1102
|
+
.insertInto("state_all")
|
|
1103
|
+
.values({
|
|
1104
|
+
entity_id: "global-entity-1",
|
|
1105
|
+
file_id: "test-file",
|
|
1106
|
+
schema_key: "test_schema",
|
|
1107
|
+
plugin_key: "test_plugin",
|
|
1108
|
+
version_id: "global",
|
|
1109
|
+
snapshot_content: {
|
|
1110
|
+
id: "global-entity-1",
|
|
1111
|
+
name: "Global Entity",
|
|
1112
|
+
},
|
|
1113
|
+
schema_version: "1.0",
|
|
1114
|
+
})
|
|
1115
|
+
.execute();
|
|
1116
|
+
// Create a child version that inherits from global
|
|
1117
|
+
const childVersion = await createVersion({
|
|
1118
|
+
lix,
|
|
1119
|
+
name: "child-version",
|
|
1120
|
+
});
|
|
1121
|
+
// Verify inheritance was set up correctly
|
|
1122
|
+
expect(childVersion.inherits_from_version_id).toBe("global");
|
|
1123
|
+
if (clearCache) {
|
|
1124
|
+
// Clear the state cache to force re-materialization with inheritance (CTE path)
|
|
1125
|
+
lix.sqlite.exec("DELETE FROM internal_state_cache");
|
|
1126
|
+
}
|
|
1127
|
+
// If clearCache is false, we test the cache hit path
|
|
1128
|
+
// The child version should inherit the entity from global
|
|
1129
|
+
const inheritedEntity = await lix.db
|
|
1130
|
+
.selectFrom("state_all")
|
|
1131
|
+
.where("entity_id", "=", "global-entity-1")
|
|
1132
|
+
.where("version_id", "=", childVersion.id)
|
|
1133
|
+
.selectAll()
|
|
1134
|
+
.execute();
|
|
1135
|
+
// This should pass - the entity should be visible in the child version via inheritance
|
|
1136
|
+
expect(inheritedEntity).toHaveLength(1);
|
|
1137
|
+
expect(inheritedEntity[0]?.entity_id).toBe("global-entity-1");
|
|
1138
|
+
expect(inheritedEntity[0]?.version_id).toBe(childVersion.id); // Should return child version ID
|
|
1139
|
+
expect(inheritedEntity[0]?.inherited_from_version_id).toBe("global"); // Should track inheritance source
|
|
1140
|
+
expect(inheritedEntity[0]?.snapshot_content).toEqual({
|
|
1141
|
+
id: "global-entity-1",
|
|
1142
|
+
name: "Global Entity",
|
|
1143
|
+
});
|
|
1144
|
+
});
|
|
1145
|
+
// Flaky cache CTE
|
|
1146
|
+
test.todo("inherited entities should reflect changes in parent", async () => {
|
|
1147
|
+
const lix = await openLix({});
|
|
1148
|
+
// Get the main version
|
|
1149
|
+
const mainVersion = await lix.db
|
|
1150
|
+
.selectFrom("version")
|
|
1151
|
+
.where("name", "=", "main")
|
|
1152
|
+
.selectAll()
|
|
1153
|
+
.executeTakeFirstOrThrow();
|
|
1154
|
+
const originalChangeSetId = mainVersion.change_set_id;
|
|
1155
|
+
// Make a mutation to trigger version update in global context
|
|
1156
|
+
await lix.db
|
|
1157
|
+
.insertInto("key_value_all")
|
|
1158
|
+
.values({
|
|
1159
|
+
key: "cache_rebuild_test_key",
|
|
1160
|
+
value: "cache_rebuild_test_value",
|
|
1161
|
+
lixcol_version_id: mainVersion.id,
|
|
1162
|
+
})
|
|
1163
|
+
.execute();
|
|
1164
|
+
// Check the global version after mutation
|
|
1165
|
+
const globalVersionAfterMutation = await lix.db
|
|
1166
|
+
.selectFrom("state_all")
|
|
1167
|
+
.where("schema_key", "=", "lix_version")
|
|
1168
|
+
.where("entity_id", "=", mainVersion.id)
|
|
1169
|
+
.where("version_id", "=", "global")
|
|
1170
|
+
.selectAll()
|
|
1171
|
+
.executeTakeFirst();
|
|
1172
|
+
console.log("🌍 Global version after mutation:", {
|
|
1173
|
+
change_set_id: globalVersionAfterMutation?.snapshot_content
|
|
1174
|
+
?.change_set_id,
|
|
1175
|
+
original: originalChangeSetId,
|
|
1176
|
+
});
|
|
1177
|
+
if (clearCache) {
|
|
1178
|
+
// Clear the cache to force a rebuild from CTE
|
|
1179
|
+
await lix.db
|
|
1180
|
+
.deleteFrom("internal_state_cache")
|
|
1181
|
+
.execute();
|
|
1182
|
+
}
|
|
1183
|
+
const state = await lix.db
|
|
1184
|
+
.selectFrom("state_all")
|
|
1185
|
+
.where("schema_key", "=", "lix_version")
|
|
1186
|
+
.where("entity_id", "=", mainVersion.id)
|
|
1187
|
+
.selectAll()
|
|
1188
|
+
.execute();
|
|
1189
|
+
console.log("🔍 State query result:", state.map((s) => ({
|
|
1190
|
+
entity_id: s.entity_id,
|
|
1191
|
+
version_id: s.version_id,
|
|
1192
|
+
change_set_id: s.snapshot_content.change_set_id,
|
|
1193
|
+
inherited_from_version_id: s.inherited_from_version_id,
|
|
1194
|
+
})));
|
|
1195
|
+
// testing for cached contents first to make a cache miss test fail faster
|
|
1196
|
+
const cacheContents = await lix.db
|
|
1197
|
+
.selectFrom("internal_state_cache")
|
|
1198
|
+
.where("schema_key", "=", "lix_version")
|
|
1199
|
+
.where("entity_id", "=", mainVersion.id)
|
|
1200
|
+
.selectAll()
|
|
1201
|
+
.execute();
|
|
1202
|
+
// Both version entries should have the same updated change_set_id
|
|
1203
|
+
const cachedInheritedMainVersion = cacheContents.find((entry) => entry.version_id === mainVersion.id);
|
|
1204
|
+
const cachedMainVersionGlobal = cacheContents.find((entry) => entry.version_id === "global");
|
|
1205
|
+
// we have copy on write deletion in place, so the cache should not contain the inherited version
|
|
1206
|
+
expect(cachedInheritedMainVersion).toBeUndefined();
|
|
1207
|
+
expect(cachedMainVersionGlobal).toBeDefined();
|
|
1208
|
+
// Both version entries should have the same updated change_set_id
|
|
1209
|
+
const inheritedMainVersion = state.find((entry) => entry.version_id === mainVersion.id);
|
|
1210
|
+
const mainVersionGlobal = state.find((entry) => entry.version_id === "global");
|
|
1211
|
+
expect(inheritedMainVersion).toBeDefined();
|
|
1212
|
+
expect(mainVersionGlobal).toBeDefined();
|
|
1213
|
+
// Both should have the same change_set_id
|
|
1214
|
+
expect((inheritedMainVersion?.snapshot_content).change_set_id).toEqual((mainVersionGlobal?.snapshot_content).change_set_id);
|
|
1215
|
+
// The change_set_id should be different from the original change_set_Id
|
|
1216
|
+
expect((inheritedMainVersion?.snapshot_content).change_set_id).not.toEqual(originalChangeSetId);
|
|
1217
|
+
expect((mainVersionGlobal?.snapshot_content).change_set_id).not.toEqual(originalChangeSetId);
|
|
1218
|
+
expect((cachedMainVersionGlobal?.snapshot_content).change_set_id).toEqual(mainVersionGlobal?.snapshot_content.change_set_id);
|
|
1219
|
+
});
|
|
1220
|
+
});
|
|
1221
|
+
// TODO flaky test https://github.com/opral/lix-sdk/issues/308
|
|
1222
|
+
describe.skip.each([
|
|
1223
|
+
{ scenario: "cache hit", clearCache: false },
|
|
1224
|
+
{ scenario: "cache miss", clearCache: true },
|
|
1225
|
+
])("($scenario) updating an inherited entity in child version should create a copy-on-write entity", () => {
|
|
1226
|
+
test("child version inherits then overrides with own entity", async () => {
|
|
1227
|
+
const lix = await openLix({});
|
|
1228
|
+
// Insert an entity into global version
|
|
1229
|
+
await lix.db
|
|
1230
|
+
.insertInto("state_all")
|
|
1231
|
+
.values({
|
|
1232
|
+
entity_id: "shared-entity",
|
|
1233
|
+
file_id: "test-file",
|
|
1234
|
+
schema_key: "test_schema",
|
|
1235
|
+
plugin_key: "test_plugin",
|
|
1236
|
+
version_id: "global",
|
|
1237
|
+
snapshot_content: {
|
|
1238
|
+
id: "shared-entity",
|
|
1239
|
+
name: "Original Global Value",
|
|
1240
|
+
count: 1,
|
|
1241
|
+
},
|
|
1242
|
+
schema_version: "1.0",
|
|
1243
|
+
})
|
|
1244
|
+
.execute();
|
|
1245
|
+
// Create a child version that inherits from global
|
|
1246
|
+
const childVersion = await createVersion({
|
|
1247
|
+
lix,
|
|
1248
|
+
name: "child-version",
|
|
1249
|
+
});
|
|
1250
|
+
// Note: For cache miss testing, we'll clear cache AFTER the update operation
|
|
1251
|
+
// Verify the child initially sees the inherited entity
|
|
1252
|
+
const inheritedEntity = await lix.db
|
|
1253
|
+
.selectFrom("state_all")
|
|
1254
|
+
.where("entity_id", "=", "shared-entity")
|
|
1255
|
+
.where("version_id", "=", childVersion.id)
|
|
1256
|
+
.selectAll()
|
|
1257
|
+
.execute();
|
|
1258
|
+
expect(inheritedEntity).toHaveLength(1);
|
|
1259
|
+
expect(inheritedEntity[0]?.version_id).toBe(childVersion.id);
|
|
1260
|
+
expect(inheritedEntity[0]?.inherited_from_version_id).toBe("global");
|
|
1261
|
+
expect(inheritedEntity[0]?.snapshot_content).toEqual({
|
|
1262
|
+
id: "shared-entity",
|
|
1263
|
+
name: "Original Global Value",
|
|
1264
|
+
count: 1,
|
|
1265
|
+
});
|
|
1266
|
+
// Now modify the entity in the child version (copy-on-write)
|
|
1267
|
+
await lix.db
|
|
1268
|
+
.updateTable("state_all")
|
|
1269
|
+
.set({
|
|
1270
|
+
snapshot_content: {
|
|
1271
|
+
id: "shared-entity",
|
|
1272
|
+
name: "Modified in Child Version",
|
|
1273
|
+
count: 2,
|
|
1274
|
+
},
|
|
1275
|
+
})
|
|
1276
|
+
.where("entity_id", "=", "shared-entity")
|
|
1277
|
+
.where("version_id", "=", childVersion.id)
|
|
1278
|
+
.execute();
|
|
1279
|
+
// Clear cache after update to test cache miss scenario
|
|
1280
|
+
// if (clearCache) {
|
|
1281
|
+
// lix.sqlite.exec("DELETE FROM internal_state_cache");
|
|
1282
|
+
// }
|
|
1283
|
+
// Verify the child now has its own version of the entity
|
|
1284
|
+
const childEntity = await lix.db
|
|
1285
|
+
.selectFrom("state_all")
|
|
1286
|
+
.where("entity_id", "=", "shared-entity")
|
|
1287
|
+
.where("version_id", "=", childVersion.id)
|
|
1288
|
+
.selectAll()
|
|
1289
|
+
.execute();
|
|
1290
|
+
expect(childEntity).toHaveLength(1);
|
|
1291
|
+
expect(childEntity[0]?.version_id).toBe(childVersion.id);
|
|
1292
|
+
expect(childEntity[0]?.inherited_from_version_id).toBe(null); // No longer inherited
|
|
1293
|
+
expect(childEntity[0]?.snapshot_content).toEqual({
|
|
1294
|
+
id: "shared-entity",
|
|
1295
|
+
name: "Modified in Child Version",
|
|
1296
|
+
count: 2,
|
|
1297
|
+
});
|
|
1298
|
+
// Verify the global version still has the original value
|
|
1299
|
+
const globalEntity = await lix.db
|
|
1300
|
+
.selectFrom("state_all")
|
|
1301
|
+
.where("entity_id", "=", "shared-entity")
|
|
1302
|
+
.where("version_id", "=", "global")
|
|
1303
|
+
.selectAll()
|
|
1304
|
+
.execute();
|
|
1305
|
+
expect(globalEntity).toHaveLength(1);
|
|
1306
|
+
expect(globalEntity[0]?.version_id).toBe("global");
|
|
1307
|
+
expect(globalEntity[0]?.inherited_from_version_id).toBe(null);
|
|
1308
|
+
expect(globalEntity[0]?.snapshot_content).toEqual({
|
|
1309
|
+
id: "shared-entity",
|
|
1310
|
+
name: "Original Global Value",
|
|
1311
|
+
count: 1,
|
|
1312
|
+
});
|
|
1313
|
+
// Verify we now have 2 separate entities (one in global, one in child)
|
|
1314
|
+
const allEntities = await lix.db
|
|
1315
|
+
.selectFrom("state_all")
|
|
1316
|
+
.where("entity_id", "=", "shared-entity")
|
|
1317
|
+
.selectAll()
|
|
1318
|
+
.execute();
|
|
1319
|
+
expect(allEntities).toHaveLength(2);
|
|
1320
|
+
// Sort by version_id for consistent ordering
|
|
1321
|
+
allEntities.sort((a, b) => a.version_id.localeCompare(b.version_id));
|
|
1322
|
+
// Child version entity (modified)
|
|
1323
|
+
expect(allEntities[0]?.version_id).toBe(childVersion.id);
|
|
1324
|
+
expect(allEntities[0]?.inherited_from_version_id).toBe(null);
|
|
1325
|
+
expect(allEntities[0]?.snapshot_content).toEqual({
|
|
1326
|
+
id: "shared-entity",
|
|
1327
|
+
name: "Modified in Child Version",
|
|
1328
|
+
count: 2,
|
|
1329
|
+
});
|
|
1330
|
+
// Global version entity (original)
|
|
1331
|
+
expect(allEntities[1]?.version_id).toBe("global");
|
|
1332
|
+
expect(allEntities[1]?.inherited_from_version_id).toBe(null);
|
|
1333
|
+
expect(allEntities[1]?.snapshot_content).toEqual({
|
|
1334
|
+
id: "shared-entity",
|
|
1335
|
+
name: "Original Global Value",
|
|
1336
|
+
count: 1,
|
|
1337
|
+
});
|
|
1338
|
+
});
|
|
1339
|
+
});
|
|
1340
|
+
describe.each([
|
|
1341
|
+
{ scenario: "cache hit", clearCache: false },
|
|
1342
|
+
{ scenario: "cache miss", clearCache: true },
|
|
1343
|
+
])("($scenario) deleting an inherited entity should create copy-on-write deletion", ({ clearCache }) => {
|
|
1344
|
+
test.todo("child version deletes inherited entity via copy-on-write", async () => {
|
|
1345
|
+
const mockSchema = {
|
|
1346
|
+
"x-lix-key": "test_schema",
|
|
1347
|
+
"x-lix-version": "1.0",
|
|
1348
|
+
type: "object",
|
|
1349
|
+
additionalProperties: false,
|
|
1350
|
+
properties: {
|
|
1351
|
+
id: { type: "string" },
|
|
1352
|
+
name: { type: "string" },
|
|
1353
|
+
},
|
|
1354
|
+
};
|
|
1355
|
+
const lix = await openLix({});
|
|
1356
|
+
const activeVersion = await lix.db
|
|
1357
|
+
.selectFrom("active_version")
|
|
1358
|
+
.innerJoin("version", "active_version.version_id", "version.id")
|
|
1359
|
+
.selectAll("version")
|
|
1360
|
+
.executeTakeFirstOrThrow();
|
|
1361
|
+
// Insert schema
|
|
1362
|
+
await lix.db
|
|
1363
|
+
.insertInto("stored_schema")
|
|
1364
|
+
.values({ value: mockSchema })
|
|
1365
|
+
.execute();
|
|
1366
|
+
// Insert an entity into global version
|
|
1367
|
+
await lix.db
|
|
1368
|
+
.insertInto("state_all")
|
|
1369
|
+
.values({
|
|
1370
|
+
entity_id: "shared-entity",
|
|
1371
|
+
file_id: "test-file",
|
|
1372
|
+
schema_key: "test_schema",
|
|
1373
|
+
plugin_key: "test_plugin",
|
|
1374
|
+
version_id: "global",
|
|
1375
|
+
snapshot_content: {
|
|
1376
|
+
id: "shared-entity",
|
|
1377
|
+
name: "shared Entity",
|
|
1378
|
+
},
|
|
1379
|
+
schema_version: "1.0",
|
|
1380
|
+
})
|
|
1381
|
+
.execute();
|
|
1382
|
+
if (clearCache) {
|
|
1383
|
+
// Clear the state cache to force re-materialization with inheritance (CTE path)
|
|
1384
|
+
lix.sqlite.exec("DELETE FROM internal_state_cache");
|
|
1385
|
+
}
|
|
1386
|
+
// If clearCache is false, we test the cache hit path
|
|
1387
|
+
// Verify the child initially sees the inherited entity
|
|
1388
|
+
const inheritedEntity = await lix.db
|
|
1389
|
+
.selectFrom("state_all")
|
|
1390
|
+
.where("entity_id", "=", "shared-entity")
|
|
1391
|
+
.where("version_id", "=", activeVersion.id)
|
|
1392
|
+
.selectAll()
|
|
1393
|
+
.execute();
|
|
1394
|
+
expect(inheritedEntity).toHaveLength(1);
|
|
1395
|
+
expect(inheritedEntity[0]?.version_id).toBe(activeVersion.id);
|
|
1396
|
+
expect(inheritedEntity[0]?.inherited_from_version_id).toBe("global");
|
|
1397
|
+
// Delete the inherited entity in child version (should create copy-on-write deletion)
|
|
1398
|
+
await lix.db
|
|
1399
|
+
.deleteFrom("state_all")
|
|
1400
|
+
.where("entity_id", "=", "shared-entity")
|
|
1401
|
+
.where("version_id", "=", activeVersion.id)
|
|
1402
|
+
.execute();
|
|
1403
|
+
if (clearCache) {
|
|
1404
|
+
// Clear cache after deletion to test CTE path for subsequent queries
|
|
1405
|
+
lix.sqlite.exec("DELETE FROM internal_state_cache");
|
|
1406
|
+
}
|
|
1407
|
+
// Verify the entity is deleted in child version
|
|
1408
|
+
const childEntityAfterDelete = await lix.db
|
|
1409
|
+
.selectFrom("state_all")
|
|
1410
|
+
.where("entity_id", "=", "shared-entity")
|
|
1411
|
+
.where("version_id", "=", activeVersion.id)
|
|
1412
|
+
.selectAll()
|
|
1413
|
+
.execute();
|
|
1414
|
+
// Entity should be deleted in child version (copy-on-write deletion)
|
|
1415
|
+
expect(childEntityAfterDelete).toHaveLength(0);
|
|
1416
|
+
// Verify the entity still exists in global version (not affected by child deletion)
|
|
1417
|
+
const inheritedEntityAfterDelete = await lix.db
|
|
1418
|
+
.selectFrom("state_all")
|
|
1419
|
+
.where("entity_id", "=", "shared-entity")
|
|
1420
|
+
.where("version_id", "=", "global")
|
|
1421
|
+
.selectAll()
|
|
1422
|
+
.execute();
|
|
1423
|
+
expect(inheritedEntityAfterDelete).toHaveLength(1);
|
|
1424
|
+
expect(inheritedEntityAfterDelete[0]?.snapshot_content).toEqual({
|
|
1425
|
+
id: "shared-entity",
|
|
1426
|
+
name: "shared Entity",
|
|
1427
|
+
});
|
|
1428
|
+
// Verify we now only see the global entity through the state view (deletion marker is hidden)
|
|
1429
|
+
const allEntities = await lix.db
|
|
1430
|
+
.selectFrom("state_all")
|
|
1431
|
+
.where("entity_id", "=", "shared-entity")
|
|
1432
|
+
.selectAll()
|
|
1433
|
+
.execute();
|
|
1434
|
+
// Debug: Log what entities we actually got in cache miss scenario
|
|
1435
|
+
if (clearCache && allEntities.length !== 1) {
|
|
1436
|
+
console.log(`Cache miss scenario returned ${allEntities.length} entities:`, allEntities.map((e) => ({
|
|
1437
|
+
version_id: e.version_id,
|
|
1438
|
+
inherited_from_version_id: e.inherited_from_version_id,
|
|
1439
|
+
snapshot_content: e.snapshot_content,
|
|
1440
|
+
})));
|
|
1441
|
+
}
|
|
1442
|
+
// Both cache hit and cache miss scenarios should behave identically:
|
|
1443
|
+
// copy-on-write deletion hides the entity from child but preserves it in parent
|
|
1444
|
+
expect(allEntities).toHaveLength(1);
|
|
1445
|
+
expect(allEntities[0]?.version_id).toBe("global");
|
|
1446
|
+
expect(allEntities[0]?.inherited_from_version_id).toBe(null); // It's the original global entity
|
|
1447
|
+
});
|
|
1448
|
+
});
|
|
1449
|
+
// TODO flaky test (ordering of deletions)
|
|
1450
|
+
test.todo("deleting without filtering for the version_id deletes the entity from all versions", async () => {
|
|
1451
|
+
const lix = await openLix({});
|
|
1452
|
+
// Insert an entity into global version
|
|
1453
|
+
await lix.db
|
|
1454
|
+
.insertInto("state_all")
|
|
1455
|
+
.values({
|
|
1456
|
+
entity_id: "shared-entity",
|
|
1457
|
+
file_id: "test-file",
|
|
1458
|
+
schema_key: "test_schema",
|
|
1459
|
+
plugin_key: "test_plugin",
|
|
1460
|
+
version_id: "global",
|
|
1461
|
+
snapshot_content: {
|
|
1462
|
+
id: "shared-entity",
|
|
1463
|
+
name: "Global Entity",
|
|
1464
|
+
},
|
|
1465
|
+
schema_version: "1.0",
|
|
1466
|
+
})
|
|
1467
|
+
.execute();
|
|
1468
|
+
// Create a child version that inherits from global
|
|
1469
|
+
const childVersion = await createVersion({
|
|
1470
|
+
lix,
|
|
1471
|
+
name: "child-version",
|
|
1472
|
+
inherits_from_version_id: "global",
|
|
1473
|
+
});
|
|
1474
|
+
// Verify inheritance - both global and child should see the entity
|
|
1475
|
+
const beforeDelete = await lix.db
|
|
1476
|
+
.selectFrom("state_all")
|
|
1477
|
+
.where("entity_id", "=", "shared-entity")
|
|
1478
|
+
.where("version_id", "in", ["global", childVersion.id])
|
|
1479
|
+
.selectAll()
|
|
1480
|
+
.execute();
|
|
1481
|
+
expect(beforeDelete).toHaveLength(2); // One in global, one inherited in child
|
|
1482
|
+
expect(beforeDelete).toMatchObject([
|
|
1483
|
+
{
|
|
1484
|
+
entity_id: "shared-entity",
|
|
1485
|
+
version_id: "global",
|
|
1486
|
+
inherited_from_version_id: null,
|
|
1487
|
+
snapshot_content: { id: "shared-entity", name: "Global Entity" },
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
entity_id: "shared-entity",
|
|
1491
|
+
version_id: childVersion.id,
|
|
1492
|
+
inherited_from_version_id: "global",
|
|
1493
|
+
snapshot_content: { id: "shared-entity", name: "Global Entity" },
|
|
1494
|
+
},
|
|
1495
|
+
]);
|
|
1496
|
+
await lix.db
|
|
1497
|
+
.deleteFrom("state_all")
|
|
1498
|
+
.where("entity_id", "=", "shared-entity")
|
|
1499
|
+
.where("schema_key", "=", "test_schema")
|
|
1500
|
+
.execute();
|
|
1501
|
+
const afterDelete = await lix.db
|
|
1502
|
+
.selectFrom("state_all")
|
|
1503
|
+
.where("entity_id", "=", "shared-entity")
|
|
1504
|
+
.selectAll()
|
|
1505
|
+
.execute();
|
|
1506
|
+
// Should be deleted from every version
|
|
1507
|
+
expect(afterDelete).toHaveLength(0);
|
|
1508
|
+
});
|
|
1509
|
+
// todo @martin-lysk the insert or ignore is not working as expected
|
|
1510
|
+
// i am not fixing this now to avoid merge conflicts in the xUpdate function
|
|
1511
|
+
test.todo("INSERT OR IGNORE into state virtual table should not throw validation errors for duplicates or update the row", async () => {
|
|
1512
|
+
const lix = await openLix({});
|
|
1513
|
+
// First, insert a record successfully
|
|
1514
|
+
await lix.db
|
|
1515
|
+
.insertInto("state_all")
|
|
1516
|
+
.values({
|
|
1517
|
+
entity_id: "test-duplicate-entity",
|
|
1518
|
+
schema_key: "test_schema",
|
|
1519
|
+
file_id: "test",
|
|
1520
|
+
plugin_key: "test_plugin",
|
|
1521
|
+
snapshot_content: { id: "test-duplicate-entity", name: "Original" },
|
|
1522
|
+
schema_version: "1.0",
|
|
1523
|
+
version_id: "global",
|
|
1524
|
+
})
|
|
1525
|
+
.execute();
|
|
1526
|
+
// Verify the record exists
|
|
1527
|
+
const originalRecord = await lix.db
|
|
1528
|
+
.selectFrom("state_all")
|
|
1529
|
+
.where("entity_id", "=", "test-duplicate-entity")
|
|
1530
|
+
.selectAll()
|
|
1531
|
+
.executeTakeFirst();
|
|
1532
|
+
expect(originalRecord).toBeDefined();
|
|
1533
|
+
expect(originalRecord?.snapshot_content).toMatchObject({
|
|
1534
|
+
id: "test-duplicate-entity",
|
|
1535
|
+
name: "Original",
|
|
1536
|
+
});
|
|
1537
|
+
// Now try to INSERT OR IGNORE the same entity - this should NOT throw an error
|
|
1538
|
+
// but currently it does because validation runs before OR IGNORE logic
|
|
1539
|
+
expect(() => {
|
|
1540
|
+
lix.sqlite.exec(`
|
|
1541
|
+
INSERT OR IGNORE INTO state (
|
|
1542
|
+
entity_id, schema_key, file_id, plugin_key,
|
|
1543
|
+
snapshot_content, schema_version, version_id
|
|
1544
|
+
) VALUES (
|
|
1545
|
+
'test-duplicate-entity', 'test_schema', 'test', 'test_plugin',
|
|
1546
|
+
'{"id":"test-duplicate-entity","name":"Duplicate"}', '1.0', 'global'
|
|
1547
|
+
)
|
|
1548
|
+
`);
|
|
1549
|
+
}).not.toThrow(); // This should not throw, but currently does
|
|
1550
|
+
// Verify the original record is unchanged (OR IGNORE should have ignored the duplicate)
|
|
1551
|
+
const afterIgnore = await lix.db
|
|
1552
|
+
.selectFrom("state_all")
|
|
1553
|
+
.where("entity_id", "=", "test-duplicate-entity")
|
|
1554
|
+
.selectAll()
|
|
1555
|
+
.executeTakeFirst();
|
|
1556
|
+
expect(afterIgnore?.snapshot_content).toMatchObject({
|
|
1557
|
+
id: "test-duplicate-entity",
|
|
1558
|
+
name: "Original", // Should still be original, not "Duplicate"
|
|
1559
|
+
});
|
|
1560
|
+
});
|
|
1561
|
+
test("should emit state_commit hook when database transaction commits", async () => {
|
|
1562
|
+
const lix = await openLix({});
|
|
1563
|
+
const mockSchema = {
|
|
1564
|
+
"x-lix-key": "mock_schema",
|
|
1565
|
+
"x-lix-version": "1.0",
|
|
1566
|
+
type: "object",
|
|
1567
|
+
additionalProperties: false,
|
|
1568
|
+
properties: {
|
|
1569
|
+
value: {
|
|
1570
|
+
type: "string",
|
|
1571
|
+
},
|
|
1572
|
+
},
|
|
1573
|
+
};
|
|
1574
|
+
await lix.db
|
|
1575
|
+
.insertInto("stored_schema")
|
|
1576
|
+
.values({ value: mockSchema })
|
|
1577
|
+
.execute();
|
|
1578
|
+
// Set up hook listener
|
|
1579
|
+
let hookCallCount = 0;
|
|
1580
|
+
lix.hooks.onStateCommit(() => {
|
|
1581
|
+
hookCallCount++;
|
|
1582
|
+
});
|
|
1583
|
+
// Perform a database operation that should trigger the hook
|
|
1584
|
+
await lix.db
|
|
1585
|
+
.insertInto("state_all")
|
|
1586
|
+
.values({
|
|
1587
|
+
entity_id: "test-entity",
|
|
1588
|
+
file_id: "test-file",
|
|
1589
|
+
schema_key: "mock_schema",
|
|
1590
|
+
plugin_key: "test_plugin",
|
|
1591
|
+
schema_version: "1.0",
|
|
1592
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1593
|
+
snapshot_content: {
|
|
1594
|
+
value: "test value",
|
|
1595
|
+
},
|
|
1596
|
+
})
|
|
1597
|
+
.execute();
|
|
1598
|
+
// Hook should have been called once
|
|
1599
|
+
expect(hookCallCount).toBe(1);
|
|
1600
|
+
// Perform another operation
|
|
1601
|
+
await lix.db
|
|
1602
|
+
.updateTable("state_all")
|
|
1603
|
+
.set({
|
|
1604
|
+
snapshot_content: {
|
|
1605
|
+
value: "updated value",
|
|
1606
|
+
},
|
|
1607
|
+
})
|
|
1608
|
+
.where("entity_id", "=", "test-entity")
|
|
1609
|
+
.execute();
|
|
1610
|
+
// Hook should have been called twice now
|
|
1611
|
+
expect(hookCallCount).toBe(2);
|
|
1612
|
+
});
|
|
1613
|
+
test("untracked mutations don't trigger change control", async () => {
|
|
1614
|
+
const lix = await openLix({});
|
|
1615
|
+
const mockSchema = {
|
|
1616
|
+
"x-lix-key": "mock_schema",
|
|
1617
|
+
"x-lix-version": "1.0",
|
|
1618
|
+
type: "object",
|
|
1619
|
+
additionalProperties: false,
|
|
1620
|
+
properties: {
|
|
1621
|
+
value: {
|
|
1622
|
+
type: "string",
|
|
1623
|
+
},
|
|
1624
|
+
},
|
|
1625
|
+
};
|
|
1626
|
+
await lix.db
|
|
1627
|
+
.insertInto("stored_schema")
|
|
1628
|
+
.values({ value: mockSchema })
|
|
1629
|
+
.execute();
|
|
1630
|
+
// Count changes before any untracked mutations
|
|
1631
|
+
const changesInitial = await lix.db
|
|
1632
|
+
.selectFrom("change")
|
|
1633
|
+
.selectAll()
|
|
1634
|
+
.execute();
|
|
1635
|
+
// 1. INSERT untracked state
|
|
1636
|
+
await lix.db
|
|
1637
|
+
.insertInto("state_all")
|
|
1638
|
+
.values({
|
|
1639
|
+
entity_id: "untracked-entity",
|
|
1640
|
+
file_id: "test-file",
|
|
1641
|
+
schema_key: "mock_schema",
|
|
1642
|
+
plugin_key: "test_plugin",
|
|
1643
|
+
schema_version: "1.0",
|
|
1644
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1645
|
+
snapshot_content: {
|
|
1646
|
+
value: "untracked value",
|
|
1647
|
+
},
|
|
1648
|
+
untracked: true,
|
|
1649
|
+
})
|
|
1650
|
+
.execute();
|
|
1651
|
+
// Count changes after untracked insert
|
|
1652
|
+
const changesAfterInsert = await lix.db
|
|
1653
|
+
.selectFrom("change")
|
|
1654
|
+
.selectAll()
|
|
1655
|
+
.execute();
|
|
1656
|
+
// Number of changes should be identical (no change control for untracked)
|
|
1657
|
+
expect(changesAfterInsert.length).toBe(changesInitial.length);
|
|
1658
|
+
// Verify the untracked entity exists in state view
|
|
1659
|
+
const untrackedState = await lix.db
|
|
1660
|
+
.selectFrom("state_all")
|
|
1661
|
+
.where("entity_id", "=", "untracked-entity")
|
|
1662
|
+
.selectAll()
|
|
1663
|
+
.execute();
|
|
1664
|
+
expect(untrackedState).toHaveLength(1);
|
|
1665
|
+
expect(untrackedState[0]?.snapshot_content).toEqual({
|
|
1666
|
+
value: "untracked value",
|
|
1667
|
+
});
|
|
1668
|
+
expect(untrackedState[0]?.untracked).toBe(1);
|
|
1669
|
+
// 2. UPDATE untracked state
|
|
1670
|
+
await lix.db
|
|
1671
|
+
.updateTable("state_all")
|
|
1672
|
+
.where("entity_id", "=", "untracked-entity")
|
|
1673
|
+
.set({
|
|
1674
|
+
snapshot_content: {
|
|
1675
|
+
value: "untracked value updated",
|
|
1676
|
+
},
|
|
1677
|
+
untracked: true,
|
|
1678
|
+
})
|
|
1679
|
+
.execute();
|
|
1680
|
+
// Count changes after untracked update
|
|
1681
|
+
const changesAfterUpdate = await lix.db
|
|
1682
|
+
.selectFrom("change")
|
|
1683
|
+
.selectAll()
|
|
1684
|
+
.execute();
|
|
1685
|
+
// Number of changes should still be identical (no change control for untracked)
|
|
1686
|
+
expect(changesAfterUpdate.length).toBe(changesInitial.length);
|
|
1687
|
+
// Verify the untracked entity was updated
|
|
1688
|
+
const updatedState = await lix.db
|
|
1689
|
+
.selectFrom("state_all")
|
|
1690
|
+
.where("entity_id", "=", "untracked-entity")
|
|
1691
|
+
.selectAll()
|
|
1692
|
+
.execute();
|
|
1693
|
+
expect(updatedState).toHaveLength(1);
|
|
1694
|
+
expect(updatedState[0]?.snapshot_content).toEqual({
|
|
1695
|
+
value: "untracked value updated",
|
|
1696
|
+
});
|
|
1697
|
+
expect(updatedState[0]?.untracked).toBe(1);
|
|
1698
|
+
// 3. DELETE untracked state
|
|
1699
|
+
await lix.db
|
|
1700
|
+
.deleteFrom("state_all")
|
|
1701
|
+
.where("entity_id", "=", "untracked-entity")
|
|
1702
|
+
.execute();
|
|
1703
|
+
// Count changes after untracked delete
|
|
1704
|
+
const changesAfterDelete = await lix.db
|
|
1705
|
+
.selectFrom("change")
|
|
1706
|
+
.selectAll()
|
|
1707
|
+
.execute();
|
|
1708
|
+
// Number of changes should still be identical (no change control for untracked)
|
|
1709
|
+
expect(changesAfterDelete.length).toBe(changesInitial.length);
|
|
1710
|
+
// Verify the untracked entity was deleted
|
|
1711
|
+
const deletedState = await lix.db
|
|
1712
|
+
.selectFrom("state_all")
|
|
1713
|
+
.where("entity_id", "=", "untracked-entity")
|
|
1714
|
+
.selectAll()
|
|
1715
|
+
.execute();
|
|
1716
|
+
expect(deletedState).toHaveLength(0);
|
|
1717
|
+
});
|
|
1718
|
+
test("tracked update to previously untracked entity deletes untracked state", async () => {
|
|
1719
|
+
const lix = await openLix({});
|
|
1720
|
+
const mockSchema = {
|
|
1721
|
+
"x-lix-key": "mock_schema",
|
|
1722
|
+
"x-lix-version": "1.0",
|
|
1723
|
+
type: "object",
|
|
1724
|
+
additionalProperties: false,
|
|
1725
|
+
properties: {
|
|
1726
|
+
value: {
|
|
1727
|
+
type: "string",
|
|
1728
|
+
},
|
|
1729
|
+
},
|
|
1730
|
+
};
|
|
1731
|
+
await lix.db
|
|
1732
|
+
.insertInto("stored_schema")
|
|
1733
|
+
.values({ value: mockSchema })
|
|
1734
|
+
.execute();
|
|
1735
|
+
// Insert untracked state
|
|
1736
|
+
await lix.db
|
|
1737
|
+
.insertInto("state_all")
|
|
1738
|
+
.values({
|
|
1739
|
+
entity_id: "override-entity",
|
|
1740
|
+
file_id: "test-file",
|
|
1741
|
+
schema_key: "mock_schema",
|
|
1742
|
+
plugin_key: "test_plugin",
|
|
1743
|
+
schema_version: "1.0",
|
|
1744
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1745
|
+
snapshot_content: {
|
|
1746
|
+
value: "untracked value",
|
|
1747
|
+
},
|
|
1748
|
+
untracked: true,
|
|
1749
|
+
})
|
|
1750
|
+
.execute();
|
|
1751
|
+
// Verify untracked state exists
|
|
1752
|
+
const untrackedState = await lix.db
|
|
1753
|
+
.selectFrom("state_all")
|
|
1754
|
+
.where("entity_id", "=", "override-entity")
|
|
1755
|
+
.selectAll()
|
|
1756
|
+
.execute();
|
|
1757
|
+
expect(untrackedState).toHaveLength(1);
|
|
1758
|
+
expect(untrackedState[0]?.snapshot_content).toEqual({
|
|
1759
|
+
value: "untracked value",
|
|
1760
|
+
});
|
|
1761
|
+
// Now update the untracked entity to make it tracked (should delete from untracked table)
|
|
1762
|
+
await lix.db
|
|
1763
|
+
.updateTable("state_all")
|
|
1764
|
+
.set({
|
|
1765
|
+
snapshot_content: {
|
|
1766
|
+
value: "tracked value",
|
|
1767
|
+
},
|
|
1768
|
+
untracked: false,
|
|
1769
|
+
})
|
|
1770
|
+
.where("entity_id", "=", "override-entity")
|
|
1771
|
+
.where("schema_key", "=", "mock_schema")
|
|
1772
|
+
.execute();
|
|
1773
|
+
// Verify tracked state has overridden untracked state
|
|
1774
|
+
const finalState = await lix.db
|
|
1775
|
+
.selectFrom("state_all")
|
|
1776
|
+
.where("entity_id", "=", "override-entity")
|
|
1777
|
+
.selectAll()
|
|
1778
|
+
.execute();
|
|
1779
|
+
expect(finalState).toHaveLength(1);
|
|
1780
|
+
expect(finalState[0]?.snapshot_content).toEqual({
|
|
1781
|
+
value: "tracked value",
|
|
1782
|
+
});
|
|
1783
|
+
// Verify a change was created for the tracked mutation
|
|
1784
|
+
const changes = await lix.db
|
|
1785
|
+
.selectFrom("change")
|
|
1786
|
+
.where("entity_id", "=", "override-entity")
|
|
1787
|
+
.where("schema_key", "=", "mock_schema")
|
|
1788
|
+
.selectAll()
|
|
1789
|
+
.execute();
|
|
1790
|
+
expect(changes.length).toBeGreaterThan(0);
|
|
1791
|
+
});
|
|
1792
|
+
test("untracked state is persisted across lix sessions", async () => {
|
|
1793
|
+
const mockSchema = {
|
|
1794
|
+
"x-lix-key": "mock_schema",
|
|
1795
|
+
"x-lix-version": "1.0",
|
|
1796
|
+
type: "object",
|
|
1797
|
+
additionalProperties: false,
|
|
1798
|
+
properties: {
|
|
1799
|
+
value: {
|
|
1800
|
+
type: "string",
|
|
1801
|
+
},
|
|
1802
|
+
},
|
|
1803
|
+
};
|
|
1804
|
+
// First session - create and insert untracked state
|
|
1805
|
+
const lix1 = await openLix({});
|
|
1806
|
+
await lix1.db
|
|
1807
|
+
.insertInto("stored_schema")
|
|
1808
|
+
.values({ value: mockSchema })
|
|
1809
|
+
.execute();
|
|
1810
|
+
await lix1.db
|
|
1811
|
+
.insertInto("state_all")
|
|
1812
|
+
.values({
|
|
1813
|
+
entity_id: "persistent-entity",
|
|
1814
|
+
file_id: "test-file",
|
|
1815
|
+
schema_key: "mock_schema",
|
|
1816
|
+
plugin_key: "test_plugin",
|
|
1817
|
+
schema_version: "1.0",
|
|
1818
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1819
|
+
snapshot_content: {
|
|
1820
|
+
value: "persistent untracked value",
|
|
1821
|
+
},
|
|
1822
|
+
untracked: true,
|
|
1823
|
+
})
|
|
1824
|
+
.execute();
|
|
1825
|
+
// Second session - verify untracked state persists
|
|
1826
|
+
const lix2 = await openLix({ blob: await lix1.toBlob() });
|
|
1827
|
+
const persistedState = await lix2.db
|
|
1828
|
+
.selectFrom("state_all")
|
|
1829
|
+
.where("entity_id", "=", "persistent-entity")
|
|
1830
|
+
.selectAll()
|
|
1831
|
+
.execute();
|
|
1832
|
+
expect(persistedState).toHaveLength(1);
|
|
1833
|
+
expect(persistedState[0]?.snapshot_content).toEqual({
|
|
1834
|
+
value: "persistent untracked value",
|
|
1835
|
+
});
|
|
1836
|
+
await lix2.close();
|
|
1837
|
+
});
|
|
1838
|
+
test("untracked state has highest priority in UNION (untracked > tracked > inherited)", async () => {
|
|
1839
|
+
const lix = await openLix({});
|
|
1840
|
+
const mockSchema = {
|
|
1841
|
+
"x-lix-key": "mock_schema",
|
|
1842
|
+
"x-lix-version": "1.0",
|
|
1843
|
+
type: "object",
|
|
1844
|
+
additionalProperties: false,
|
|
1845
|
+
properties: {
|
|
1846
|
+
value: {
|
|
1847
|
+
type: "string",
|
|
1848
|
+
},
|
|
1849
|
+
},
|
|
1850
|
+
};
|
|
1851
|
+
await lix.db
|
|
1852
|
+
.insertInto("stored_schema")
|
|
1853
|
+
.values({ value: mockSchema })
|
|
1854
|
+
.execute();
|
|
1855
|
+
// Step 1: Insert tracked state with "init"
|
|
1856
|
+
await lix.db
|
|
1857
|
+
.insertInto("state_all")
|
|
1858
|
+
.values({
|
|
1859
|
+
entity_id: "entity0",
|
|
1860
|
+
file_id: "test-file",
|
|
1861
|
+
schema_key: "mock_schema",
|
|
1862
|
+
plugin_key: "test_plugin",
|
|
1863
|
+
schema_version: "1.0",
|
|
1864
|
+
version_id: sql `(SELECT version_id FROM active_version)`,
|
|
1865
|
+
snapshot_content: {
|
|
1866
|
+
value: "init",
|
|
1867
|
+
},
|
|
1868
|
+
untracked: false,
|
|
1869
|
+
})
|
|
1870
|
+
.execute();
|
|
1871
|
+
// Verify tracked state exists
|
|
1872
|
+
const afterInit = await lix.db
|
|
1873
|
+
.selectFrom("state_all")
|
|
1874
|
+
.where("entity_id", "=", "entity0")
|
|
1875
|
+
.selectAll()
|
|
1876
|
+
.execute();
|
|
1877
|
+
expect(afterInit).toHaveLength(1);
|
|
1878
|
+
expect(afterInit[0]?.snapshot_content).toEqual({ value: "init" });
|
|
1879
|
+
// Step 2: Update to untracked state with "update" (should NOT delete tracked state)
|
|
1880
|
+
await lix.db
|
|
1881
|
+
.updateTable("state_all")
|
|
1882
|
+
.set({
|
|
1883
|
+
snapshot_content: {
|
|
1884
|
+
value: "update",
|
|
1885
|
+
},
|
|
1886
|
+
untracked: true,
|
|
1887
|
+
})
|
|
1888
|
+
.where("entity_id", "=", "entity0")
|
|
1889
|
+
.where("schema_key", "=", "mock_schema")
|
|
1890
|
+
.execute();
|
|
1891
|
+
// Step 3: Query should return untracked state "update" (highest priority)
|
|
1892
|
+
const afterUntrackedUpdate = await lix.db
|
|
1893
|
+
.selectFrom("state_all")
|
|
1894
|
+
.where("entity_id", "=", "entity0")
|
|
1895
|
+
.selectAll()
|
|
1896
|
+
.execute();
|
|
1897
|
+
expect(afterUntrackedUpdate).toHaveLength(1);
|
|
1898
|
+
expect(afterUntrackedUpdate[0]?.snapshot_content).toEqual({
|
|
1899
|
+
value: "update",
|
|
1900
|
+
});
|
|
1901
|
+
// Step 4: Update back to tracked state with "update2" (should delete untracked state)
|
|
1902
|
+
await lix.db
|
|
1903
|
+
.updateTable("state_all")
|
|
1904
|
+
.set({
|
|
1905
|
+
snapshot_content: {
|
|
1906
|
+
value: "update2",
|
|
1907
|
+
},
|
|
1908
|
+
untracked: false,
|
|
1909
|
+
})
|
|
1910
|
+
.where("entity_id", "=", "entity0")
|
|
1911
|
+
.where("schema_key", "=", "mock_schema")
|
|
1912
|
+
.execute();
|
|
1913
|
+
// Step 5: Query should return tracked state "update2"
|
|
1914
|
+
const afterTrackedUpdate = await lix.db
|
|
1915
|
+
.selectFrom("state_all")
|
|
1916
|
+
.where("entity_id", "=", "entity0")
|
|
1917
|
+
.selectAll()
|
|
1918
|
+
.execute();
|
|
1919
|
+
expect(afterTrackedUpdate).toHaveLength(1);
|
|
1920
|
+
expect(afterTrackedUpdate[0]?.snapshot_content).toEqual({ value: "update2" });
|
|
1921
|
+
// Verify that a change was created for the final tracked mutation
|
|
1922
|
+
const changes = await lix.db
|
|
1923
|
+
.selectFrom("change")
|
|
1924
|
+
.where("entity_id", "=", "entity0")
|
|
1925
|
+
.where("schema_key", "=", "mock_schema")
|
|
1926
|
+
.selectAll()
|
|
1927
|
+
.execute();
|
|
1928
|
+
expect(changes.length).toBeGreaterThan(0);
|
|
1929
|
+
});
|
|
1930
|
+
test("untracked state overrides inherited state (untracked > inherited)", async () => {
|
|
1931
|
+
const lix = await openLix({});
|
|
1932
|
+
const mockSchema = {
|
|
1933
|
+
"x-lix-key": "mock_schema",
|
|
1934
|
+
"x-lix-version": "1.0",
|
|
1935
|
+
type: "object",
|
|
1936
|
+
additionalProperties: false,
|
|
1937
|
+
properties: {
|
|
1938
|
+
value: {
|
|
1939
|
+
type: "string",
|
|
1940
|
+
},
|
|
1941
|
+
},
|
|
1942
|
+
};
|
|
1943
|
+
await lix.db
|
|
1944
|
+
.insertInto("stored_schema")
|
|
1945
|
+
.values({ value: mockSchema })
|
|
1946
|
+
.execute();
|
|
1947
|
+
// Step 1: Insert entity in global version (will be inherited by child)
|
|
1948
|
+
await lix.db
|
|
1949
|
+
.insertInto("state_all")
|
|
1950
|
+
.values({
|
|
1951
|
+
entity_id: "inherited-entity",
|
|
1952
|
+
file_id: "test-file",
|
|
1953
|
+
schema_key: "mock_schema",
|
|
1954
|
+
plugin_key: "test_plugin",
|
|
1955
|
+
schema_version: "1.0",
|
|
1956
|
+
version_id: "global",
|
|
1957
|
+
snapshot_content: {
|
|
1958
|
+
value: "inherited value",
|
|
1959
|
+
},
|
|
1960
|
+
untracked: false,
|
|
1961
|
+
})
|
|
1962
|
+
.execute();
|
|
1963
|
+
// Step 2: Create a child version that inherits from global
|
|
1964
|
+
const childVersion = await createVersion({ lix, name: "child-version" });
|
|
1965
|
+
// Verify inheritance is set up correctly
|
|
1966
|
+
expect(childVersion.inherits_from_version_id).toBe("global");
|
|
1967
|
+
// Step 3: Verify child initially sees inherited entity
|
|
1968
|
+
const inheritedState = await lix.db
|
|
1969
|
+
.selectFrom("state_all")
|
|
1970
|
+
.where("entity_id", "=", "inherited-entity")
|
|
1971
|
+
.where("version_id", "=", childVersion.id)
|
|
1972
|
+
.selectAll()
|
|
1973
|
+
.execute();
|
|
1974
|
+
expect(inheritedState).toHaveLength(1);
|
|
1975
|
+
expect(inheritedState[0]?.snapshot_content).toEqual({
|
|
1976
|
+
value: "inherited value",
|
|
1977
|
+
});
|
|
1978
|
+
expect(inheritedState[0]?.inherited_from_version_id).toBe("global");
|
|
1979
|
+
// Step 4: Add untracked state for same entity in child version
|
|
1980
|
+
await lix.db
|
|
1981
|
+
.insertInto("state_all")
|
|
1982
|
+
.values({
|
|
1983
|
+
entity_id: "inherited-entity",
|
|
1984
|
+
file_id: "test-file",
|
|
1985
|
+
schema_key: "mock_schema",
|
|
1986
|
+
plugin_key: "test_plugin",
|
|
1987
|
+
schema_version: "1.0",
|
|
1988
|
+
version_id: childVersion.id,
|
|
1989
|
+
snapshot_content: {
|
|
1990
|
+
value: "untracked override",
|
|
1991
|
+
},
|
|
1992
|
+
untracked: true,
|
|
1993
|
+
})
|
|
1994
|
+
.execute();
|
|
1995
|
+
// Step 5: Query should return untracked state (higher priority than inherited)
|
|
1996
|
+
const finalState = await lix.db
|
|
1997
|
+
.selectFrom("state_all")
|
|
1998
|
+
.where("entity_id", "=", "inherited-entity")
|
|
1999
|
+
.where("version_id", "=", childVersion.id)
|
|
2000
|
+
.selectAll()
|
|
2001
|
+
.execute();
|
|
2002
|
+
expect(finalState).toHaveLength(1);
|
|
2003
|
+
expect(finalState[0]?.snapshot_content).toEqual({
|
|
2004
|
+
value: "untracked override",
|
|
2005
|
+
});
|
|
2006
|
+
expect(finalState[0]?.inherited_from_version_id).toBe(null); // Should not be inherited anymore
|
|
2007
|
+
expect(finalState[0]?.version_id).toBe(childVersion.id);
|
|
2008
|
+
// Step 6: Verify the inherited entity still exists in global version (unchanged)
|
|
2009
|
+
const globalState = await lix.db
|
|
2010
|
+
.selectFrom("state_all")
|
|
2011
|
+
.where("entity_id", "=", "inherited-entity")
|
|
2012
|
+
.where("version_id", "=", "global")
|
|
2013
|
+
.selectAll()
|
|
2014
|
+
.execute();
|
|
2015
|
+
expect(globalState).toHaveLength(1);
|
|
2016
|
+
expect(globalState[0]?.snapshot_content).toEqual({
|
|
2017
|
+
value: "inherited value",
|
|
2018
|
+
});
|
|
2019
|
+
expect(globalState[0]?.inherited_from_version_id).toBe(null);
|
|
2020
|
+
// Step 7: No changes should be created for untracked mutations
|
|
2021
|
+
const changes = await lix.db
|
|
2022
|
+
.selectFrom("change")
|
|
2023
|
+
.where("entity_id", "=", "inherited-entity")
|
|
2024
|
+
.where("schema_key", "=", "mock_schema")
|
|
2025
|
+
.selectAll()
|
|
2026
|
+
.execute();
|
|
2027
|
+
// Should only have the original change from global version, not the untracked one
|
|
2028
|
+
expect(changes).toHaveLength(1);
|
|
2029
|
+
});
|
|
2030
|
+
//# sourceMappingURL=schema.test.js.map
|