@lix-js/sdk 0.0.1 → 0.2.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/LICENSE +21 -0
- package/dist/account/database-schema.d.ts.map +1 -1
- package/dist/account/database-schema.js +2 -6
- package/dist/account/database-schema.js.map +1 -1
- package/dist/account/database-schema.test.js +4 -8
- package/dist/account/database-schema.test.js.map +1 -1
- package/dist/change/apply-changes.js +9 -9
- package/dist/change/apply-changes.js.map +1 -1
- package/dist/change/apply-changes.test.js +5 -5
- package/dist/change/apply-changes.test.js.map +1 -1
- package/dist/database/apply-schema.d.ts.map +1 -1
- package/dist/database/apply-schema.js +20 -72
- package/dist/database/apply-schema.js.map +1 -1
- package/dist/database/execute-sync.test.js +3 -3
- package/dist/database/execute-sync.test.js.map +1 -1
- package/dist/database/init-db.d.ts.map +1 -1
- package/dist/database/init-db.js +18 -3
- package/dist/database/init-db.js.map +1 -1
- package/dist/database/init-db.test.js +128 -17
- package/dist/database/init-db.test.js.map +1 -1
- 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 -2
- package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js.map +1 -1
- package/dist/database/mutation-log/database-schema.d.ts.map +1 -1
- package/dist/database/mutation-log/database-schema.js +1 -3
- package/dist/database/mutation-log/database-schema.js.map +1 -1
- package/dist/database/nano-id.d.ts +21 -0
- package/dist/database/nano-id.d.ts.map +1 -0
- package/dist/database/nano-id.js +58 -0
- package/dist/database/nano-id.js.map +1 -0
- package/dist/database/nano-id.test.d.ts +2 -0
- package/dist/database/nano-id.test.d.ts.map +1 -0
- package/dist/database/nano-id.test.js +13 -0
- package/dist/database/nano-id.test.js.map +1 -0
- package/dist/database/schema.d.ts +15 -23
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/discussion/create-comment.d.ts +0 -2
- package/dist/discussion/create-comment.d.ts.map +1 -1
- package/dist/discussion/create-comment.js +0 -1
- package/dist/discussion/create-comment.js.map +1 -1
- package/dist/discussion/create-discussion.d.ts +3 -5
- package/dist/discussion/create-discussion.d.ts.map +1 -1
- package/dist/discussion/create-discussion.js +4 -5
- package/dist/discussion/create-discussion.js.map +1 -1
- package/dist/discussion/create-discussion.test.js +8 -34
- package/dist/discussion/create-discussion.test.js.map +1 -1
- package/dist/file-queue/file-handlers.d.ts +24 -0
- package/dist/file-queue/file-handlers.d.ts.map +1 -0
- package/dist/file-queue/file-handlers.js +209 -0
- package/dist/file-queue/file-handlers.js.map +1 -0
- package/dist/file-queue/file-queue-process.d.ts +5 -0
- package/dist/file-queue/file-queue-process.d.ts.map +1 -0
- package/dist/file-queue/file-queue-process.js +88 -0
- package/dist/file-queue/file-queue-process.js.map +1 -0
- package/dist/file-queue/file-queue-process.test.d.ts +2 -0
- package/dist/file-queue/file-queue-process.test.d.ts.map +1 -0
- package/dist/file-queue/file-queue-process.test.js +372 -0
- package/dist/file-queue/file-queue-process.test.js.map +1 -0
- package/dist/file-queue/file-queue-settled.d.ts +13 -0
- package/dist/file-queue/file-queue-settled.d.ts.map +1 -0
- package/dist/file-queue/file-queue-settled.js +25 -0
- package/dist/file-queue/file-queue-settled.js.map +1 -0
- package/dist/file-queue/file-queue-settled.test.d.ts +2 -0
- package/dist/file-queue/file-queue-settled.test.d.ts.map +1 -0
- package/dist/file-queue/file-queue-settled.test.js +47 -0
- package/dist/file-queue/file-queue-settled.test.js.map +1 -0
- package/dist/file-queue/index.d.ts +2 -0
- package/dist/file-queue/index.d.ts.map +1 -0
- package/dist/file-queue/index.js +2 -0
- package/dist/file-queue/index.js.map +1 -0
- package/dist/file-queue/with-skip-file-queue.d.ts +3 -0
- package/dist/file-queue/with-skip-file-queue.d.ts.map +1 -0
- package/dist/file-queue/with-skip-file-queue.js +26 -0
- package/dist/file-queue/with-skip-file-queue.js.map +1 -0
- package/dist/file-queue/with-skip-file-queue.test.d.ts +2 -0
- package/dist/file-queue/with-skip-file-queue.test.d.ts.map +1 -0
- package/dist/file-queue/with-skip-file-queue.test.js +138 -0
- package/dist/file-queue/with-skip-file-queue.test.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/key-value/database-schema.d.ts +11 -2
- package/dist/key-value/database-schema.d.ts.map +1 -1
- package/dist/key-value/database-schema.js +7 -4
- package/dist/key-value/database-schema.js.map +1 -1
- package/dist/key-value/database-schema.test.js +21 -5
- package/dist/key-value/database-schema.test.js.map +1 -1
- package/dist/lix/close-lix.d.ts +8 -0
- package/dist/lix/close-lix.d.ts.map +1 -0
- package/dist/lix/close-lix.js +7 -0
- package/dist/lix/close-lix.js.map +1 -0
- package/dist/lix/index.d.ts +1 -0
- package/dist/lix/index.d.ts.map +1 -1
- package/dist/lix/index.js +1 -0
- package/dist/lix/index.js.map +1 -1
- package/dist/lix/merge.js +3 -3
- package/dist/lix/merge.js.map +1 -1
- package/dist/lix/merge.test.js +7 -18
- package/dist/lix/merge.test.js.map +1 -1
- package/dist/lix/new-lix.d.ts.map +1 -1
- package/dist/lix/new-lix.js +2 -3
- package/dist/lix/new-lix.js.map +1 -1
- package/dist/lix/open-lix-in-memory.test.js +2 -1
- package/dist/lix/open-lix-in-memory.test.js.map +1 -1
- package/dist/lix/open-lix.d.ts +19 -6
- package/dist/lix/open-lix.d.ts.map +1 -1
- package/dist/lix/open-lix.js +80 -18
- package/dist/lix/open-lix.js.map +1 -1
- package/dist/lix/open-lix.test.js +70 -7
- package/dist/lix/open-lix.test.js.map +1 -1
- package/dist/lix/to-blob.d.ts +11 -0
- package/dist/lix/to-blob.d.ts.map +1 -0
- package/dist/lix/to-blob.js +11 -0
- package/dist/lix/to-blob.js.map +1 -0
- package/dist/own-change-control/apply-own-change.d.ts +10 -0
- package/dist/own-change-control/apply-own-change.d.ts.map +1 -0
- package/dist/own-change-control/apply-own-change.js +69 -0
- package/dist/own-change-control/apply-own-change.js.map +1 -0
- package/dist/own-change-control/apply-own-change.test.d.ts +2 -0
- package/dist/own-change-control/apply-own-change.test.d.ts.map +1 -0
- package/dist/own-change-control/apply-own-change.test.js +297 -0
- package/dist/own-change-control/apply-own-change.test.js.map +1 -0
- package/dist/own-change-control/change-controlled-tables.d.ts +60 -0
- package/dist/own-change-control/change-controlled-tables.d.ts.map +1 -0
- package/dist/own-change-control/change-controlled-tables.js +70 -0
- package/dist/own-change-control/change-controlled-tables.js.map +1 -0
- package/dist/own-change-control/change-controlled-tables.test.d.ts +2 -0
- package/dist/own-change-control/change-controlled-tables.test.d.ts.map +1 -0
- package/dist/own-change-control/change-controlled-tables.test.js +48 -0
- package/dist/own-change-control/change-controlled-tables.test.js.map +1 -0
- package/dist/own-change-control/database-triggers.d.ts +5 -0
- package/dist/own-change-control/database-triggers.d.ts.map +1 -0
- package/dist/own-change-control/database-triggers.js +135 -0
- package/dist/own-change-control/database-triggers.js.map +1 -0
- package/dist/own-change-control/database-triggers.test.d.ts +2 -0
- package/dist/own-change-control/database-triggers.test.d.ts.map +1 -0
- package/dist/own-change-control/database-triggers.test.js +214 -0
- package/dist/own-change-control/database-triggers.test.js.map +1 -0
- package/dist/own-change-control/index.d.ts +2 -0
- package/dist/own-change-control/index.d.ts.map +1 -0
- package/dist/own-change-control/index.js +2 -0
- package/dist/own-change-control/index.js.map +1 -0
- package/dist/own-change-control/with-skip-own-change-control.d.ts +3 -0
- package/dist/own-change-control/with-skip-own-change-control.d.ts.map +1 -0
- package/dist/own-change-control/with-skip-own-change-control.js +28 -0
- package/dist/own-change-control/with-skip-own-change-control.js.map +1 -0
- package/dist/own-change-control/with-skip-own-change-control.test.d.ts +2 -0
- package/dist/own-change-control/with-skip-own-change-control.test.d.ts.map +1 -0
- package/dist/own-change-control/with-skip-own-change-control.test.js +49 -0
- package/dist/own-change-control/with-skip-own-change-control.test.js.map +1 -0
- package/dist/own-entity-change-control/apply-own-entity-change.js +2 -2
- package/dist/own-entity-change-control/apply-own-entity-change.js.map +1 -1
- package/dist/own-entity-change-control/apply-own-entity-change.test.js +9 -9
- package/dist/own-entity-change-control/apply-own-entity-change.test.js.map +1 -1
- package/dist/own-entity-change-control/database-triggers.js +6 -6
- package/dist/own-entity-change-control/database-triggers.js.map +1 -1
- package/dist/own-entity-change-control/database-triggers.test.js +1 -1
- package/dist/own-entity-change-control/database-triggers.test.js.map +1 -1
- package/dist/query-filter/version-change-in-difference.test.js +37 -29
- package/dist/query-filter/version-change-in-difference.test.js.map +1 -1
- package/dist/query-filter/version-change-in-symmetric-difference.test.js +37 -39
- package/dist/query-filter/version-change-in-symmetric-difference.test.js.map +1 -1
- package/dist/server-api-handler/environment/create-in-memory-environment.d.ts.map +1 -1
- package/dist/server-api-handler/environment/create-in-memory-environment.js +7 -3
- package/dist/server-api-handler/environment/create-in-memory-environment.js.map +1 -1
- package/dist/server-api-handler/environment/create-in-memory-environment.test.js +8 -7
- package/dist/server-api-handler/environment/create-in-memory-environment.test.js.map +1 -1
- package/dist/server-api-handler/routes/get-v1.d.ts.map +1 -1
- package/dist/server-api-handler/routes/get-v1.js +1 -2
- package/dist/server-api-handler/routes/get-v1.js.map +1 -1
- package/dist/server-api-handler/routes/get-v1.test.js +6 -5
- package/dist/server-api-handler/routes/get-v1.test.js.map +1 -1
- package/dist/server-api-handler/routes/new-v1.d.ts.map +1 -1
- package/dist/server-api-handler/routes/new-v1.js +3 -1
- package/dist/server-api-handler/routes/new-v1.js.map +1 -1
- package/dist/server-api-handler/routes/new-v1.test.js +2 -1
- package/dist/server-api-handler/routes/new-v1.test.js.map +1 -1
- package/dist/server-api-handler/routes/pull-v1.test.js +4 -3
- package/dist/server-api-handler/routes/pull-v1.test.js.map +1 -1
- package/dist/server-api-handler/routes/push-v1.test.js +5 -4
- package/dist/server-api-handler/routes/push-v1.test.js.map +1 -1
- package/dist/services/env-variables/index.d.ts +5 -0
- package/dist/services/env-variables/index.d.ts.map +1 -0
- package/dist/services/env-variables/index.js +5 -0
- package/dist/services/env-variables/index.js.map +1 -0
- package/dist/services/telemetry/capture.d.ts +30 -0
- package/dist/services/telemetry/capture.d.ts.map +1 -0
- package/dist/services/telemetry/capture.js +71 -0
- package/dist/services/telemetry/capture.js.map +1 -0
- package/dist/services/telemetry/capture.test.d.ts +2 -0
- package/dist/services/telemetry/capture.test.d.ts.map +1 -0
- package/dist/services/telemetry/capture.test.js +37 -0
- package/dist/services/telemetry/capture.test.js.map +1 -0
- package/dist/sync/pull-from-server.d.ts.map +1 -1
- package/dist/sync/pull-from-server.js +0 -2
- package/dist/sync/pull-from-server.js.map +1 -1
- package/dist/sync/pull-from-server.test.js +29 -14
- package/dist/sync/pull-from-server.test.js.map +1 -1
- package/dist/sync/push-to-server.test.js +17 -13
- package/dist/sync/push-to-server.test.js.map +1 -1
- package/dist/sync/sync-process.d.ts +2 -4
- package/dist/sync/sync-process.d.ts.map +1 -1
- package/dist/sync/sync-process.js +14 -13
- package/dist/sync/sync-process.js.map +1 -1
- package/dist/sync/sync-process.test.js +26 -38
- package/dist/sync/sync-process.test.js.map +1 -1
- package/dist/version/create-version.d.ts +5 -5
- package/dist/version/create-version.d.ts.map +1 -1
- package/dist/version/create-version.js +23 -11
- package/dist/version/create-version.js.map +1 -1
- package/dist/version/create-version.test.js +2 -2
- package/dist/version/create-version.test.js.map +1 -1
- package/dist/version/merge-version.d.ts.map +1 -1
- package/dist/version/merge-version.js +16 -26
- package/dist/version/merge-version.js.map +1 -1
- package/dist/version/switch-version.js +3 -3
- package/dist/version/switch-version.js.map +1 -1
- package/dist/version/switch-version.test.js +12 -15
- package/dist/version/switch-version.test.js.map +1 -1
- package/dist/version/update-changes-in-version.d.ts.map +1 -1
- package/dist/version/update-changes-in-version.js +11 -31
- package/dist/version/update-changes-in-version.js.map +1 -1
- package/package.json +7 -9
- package/src/account/database-schema.test.ts +6 -9
- package/src/account/database-schema.ts +2 -6
- package/src/change/apply-changes.test.ts +7 -7
- package/src/change/apply-changes.ts +9 -9
- package/src/database/apply-schema.ts +20 -73
- package/src/database/execute-sync.test.ts +3 -3
- package/src/database/init-db.test.ts +163 -19
- package/src/database/init-db.ts +20 -3
- package/src/database/kysely-plugin/parse-jsonb-plugin-v1.ts +9 -2
- package/src/database/mutation-log/database-schema.ts +1 -3
- package/src/database/nano-id.test.ts +15 -0
- package/src/database/nano-id.ts +72 -0
- package/src/database/schema.ts +15 -24
- package/src/discussion/create-comment.ts +0 -3
- package/src/discussion/create-discussion.test.ts +8 -39
- package/src/discussion/create-discussion.ts +6 -9
- package/src/{change-queue → file-queue}/file-handlers.ts +27 -27
- package/src/{change-queue/init-change-queue.test.ts → file-queue/file-queue-process.test.ts} +28 -29
- package/src/{change-queue/init-change-queue.ts → file-queue/file-queue-process.ts} +21 -16
- package/src/{change-queue/change-queue-settled.test.ts → file-queue/file-queue-settled.test.ts} +12 -12
- package/src/{change-queue/change-queue-settled.ts → file-queue/file-queue-settled.ts} +4 -4
- package/src/file-queue/index.ts +1 -0
- package/src/{change-queue/with-skip-change-queue.test.ts → file-queue/with-skip-file-queue.test.ts} +9 -9
- package/src/{change-queue/with-skip-change-queue.ts → file-queue/with-skip-file-queue.ts} +3 -3
- package/src/index.ts +2 -2
- package/src/key-value/database-schema.test.ts +26 -5
- package/src/key-value/database-schema.ts +18 -6
- package/src/lix/close-lix.ts +8 -0
- package/src/lix/index.ts +1 -0
- package/src/lix/merge.test.ts +7 -19
- package/src/lix/merge.ts +4 -4
- package/src/lix/new-lix.ts +2 -3
- package/src/lix/open-lix-in-memory.test.ts +5 -1
- package/src/lix/open-lix.test.ts +82 -7
- package/src/lix/open-lix.ts +104 -24
- package/src/lix/to-blob.ts +14 -0
- package/src/{own-entity-change-control/apply-own-entity-change.test.ts → own-change-control/apply-own-change.test.ts} +27 -31
- package/src/{own-entity-change-control/apply-own-entity-change.ts → own-change-control/apply-own-change.ts} +3 -3
- package/src/{own-entity-change-control → own-change-control}/change-controlled-tables.ts +0 -1
- package/src/{own-entity-change-control → own-change-control}/database-triggers.test.ts +7 -7
- package/src/{own-entity-change-control → own-change-control}/database-triggers.ts +11 -11
- package/src/{own-entity-change-control → own-change-control}/with-skip-own-change-control.ts +6 -2
- package/src/query-filter/version-change-in-difference.test.ts +41 -32
- package/src/query-filter/version-change-in-symmetric-difference.test.ts +41 -42
- package/src/server-api-handler/environment/create-in-memory-environment.test.ts +8 -7
- package/src/server-api-handler/environment/create-in-memory-environment.ts +7 -3
- package/src/server-api-handler/routes/get-v1.test.ts +6 -5
- package/src/server-api-handler/routes/get-v1.ts +1 -3
- package/src/server-api-handler/routes/new-v1.test.ts +2 -1
- package/src/server-api-handler/routes/new-v1.ts +3 -1
- package/src/server-api-handler/routes/pull-v1.test.ts +4 -3
- package/src/server-api-handler/routes/push-v1.test.ts +5 -4
- package/src/services/env-variables/create-index-file.js +35 -0
- package/src/services/env-variables/index.d.ts +15 -0
- package/src/services/telemetry/capture.test.ts +44 -0
- package/src/services/telemetry/capture.ts +99 -0
- package/src/sync/pull-from-server.test.ts +29 -14
- package/src/sync/pull-from-server.ts +0 -2
- package/src/sync/push-to-server.test.ts +19 -15
- package/src/sync/sync-process.test.ts +37 -43
- package/src/sync/sync-process.ts +16 -23
- package/src/version/create-version.test.ts +2 -2
- package/src/version/create-version.ts +24 -12
- package/src/version/merge-version.ts +18 -26
- package/src/version/switch-version.test.ts +12 -15
- package/src/version/switch-version.ts +3 -3
- package/src/version/update-changes-in-version.ts +11 -30
- package/node_modules/@lix-js/server-api-schema/.prettierrc.json +0 -3
- package/node_modules/@lix-js/server-api-schema/.vscode/extensions.json +0 -3
- package/node_modules/@lix-js/server-api-schema/dist/schema.d.ts +0 -384
- package/node_modules/@lix-js/server-api-schema/package.json +0 -21
- package/node_modules/@lix-js/server-api-schema/src/schema.yaml +0 -290
- package/node_modules/@lix-js/server-api-schema/tsconfig.json +0 -20
- package/node_modules/sqlite-wasm-kysely/README.md +0 -11
- package/node_modules/sqlite-wasm-kysely/dist/dialect.d.ts +0 -11
- package/node_modules/sqlite-wasm-kysely/dist/dialect.js +0 -13
- package/node_modules/sqlite-wasm-kysely/dist/dialect.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/index.d.ts +0 -2
- package/node_modules/sqlite-wasm-kysely/dist/index.js +0 -3
- package/node_modules/sqlite-wasm-kysely/dist/index.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/kysely/ConnectionMutex.d.ts +0 -5
- package/node_modules/sqlite-wasm-kysely/dist/kysely/ConnectionMutex.js +0 -34
- package/node_modules/sqlite-wasm-kysely/dist/kysely/ConnectionMutex.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmConnection.d.ts +0 -8
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmConnection.js +0 -57
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmConnection.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmDialectConfig.d.ts +0 -18
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmDialectConfig.js +0 -2
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmDialectConfig.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmDriver.d.ts +0 -13
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmDriver.js +0 -57
- package/node_modules/sqlite-wasm-kysely/dist/kysely/SqliteWasmDriver.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/kysely/index.d.ts +0 -4
- package/node_modules/sqlite-wasm-kysely/dist/kysely/index.js +0 -4
- package/node_modules/sqlite-wasm-kysely/dist/kysely/index.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/kysely/sqliteModule.d.ts +0 -3
- package/node_modules/sqlite-wasm-kysely/dist/kysely/sqliteModule.js +0 -5
- package/node_modules/sqlite-wasm-kysely/dist/kysely/sqliteModule.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/contentFromDatabase.d.ts +0 -9
- package/node_modules/sqlite-wasm-kysely/dist/util/contentFromDatabase.js +0 -12
- package/node_modules/sqlite-wasm-kysely/dist/util/contentFromDatabase.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/createInMemoryDatabase.d.ts +0 -3
- package/node_modules/sqlite-wasm-kysely/dist/util/createInMemoryDatabase.js +0 -22
- package/node_modules/sqlite-wasm-kysely/dist/util/createInMemoryDatabase.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/importDatabase.d.ts +0 -7
- package/node_modules/sqlite-wasm-kysely/dist/util/importDatabase.js +0 -15
- package/node_modules/sqlite-wasm-kysely/dist/util/importDatabase.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/index.d.ts +0 -5
- package/node_modules/sqlite-wasm-kysely/dist/util/index.js +0 -5
- package/node_modules/sqlite-wasm-kysely/dist/util/index.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/loadDatabaseInMemory.d.ts +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/loadDatabaseInMemory.js +0 -13
- package/node_modules/sqlite-wasm-kysely/dist/util/loadDatabaseInMemory.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/dist/util/sqliteWasmBinary.d.ts +0 -7
- package/node_modules/sqlite-wasm-kysely/dist/util/sqliteWasmBinary.js +0 -17
- package/node_modules/sqlite-wasm-kysely/dist/util/sqliteWasmBinary.js.map +0 -1
- package/node_modules/sqlite-wasm-kysely/package.json +0 -34
- package/node_modules/sqlite-wasm-kysely/src/dialect.ts +0 -15
- package/node_modules/sqlite-wasm-kysely/src/index.ts +0 -2
- package/node_modules/sqlite-wasm-kysely/src/kysely/ConnectionMutex.ts +0 -23
- package/node_modules/sqlite-wasm-kysely/src/kysely/SqliteWasmConnection.ts +0 -57
- package/node_modules/sqlite-wasm-kysely/src/kysely/SqliteWasmDialectConfig.ts +0 -19
- package/node_modules/sqlite-wasm-kysely/src/kysely/SqliteWasmDriver.ts +0 -58
- package/node_modules/sqlite-wasm-kysely/src/kysely/index.ts +0 -4
- package/node_modules/sqlite-wasm-kysely/src/kysely/sqliteModule.ts +0 -7
- package/node_modules/sqlite-wasm-kysely/src/util/contentFromDatabase.ts +0 -13
- package/node_modules/sqlite-wasm-kysely/src/util/createInMemoryDatabase.ts +0 -30
- package/node_modules/sqlite-wasm-kysely/src/util/importDatabase.ts +0 -34
- package/node_modules/sqlite-wasm-kysely/src/util/index.ts +0 -5
- package/node_modules/sqlite-wasm-kysely/src/util/loadDatabaseInMemory.ts +0 -13
- package/node_modules/sqlite-wasm-kysely/src/util/sqliteWasmBinary.ts +0 -20
- package/src/change-queue/index.ts +0 -1
- /package/src/{own-entity-change-control → own-change-control}/change-controlled-tables.test.ts +0 -0
- /package/src/{own-entity-change-control → own-change-control}/index.ts +0 -0
- /package/src/{own-entity-change-control → own-change-control}/with-skip-own-change-control.test.ts +0 -0
|
@@ -19,7 +19,7 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
19
19
|
-- file
|
|
20
20
|
|
|
21
21
|
CREATE TABLE IF NOT EXISTS file (
|
|
22
|
-
id TEXT PRIMARY KEY DEFAULT (
|
|
22
|
+
id TEXT PRIMARY KEY DEFAULT (nano_id(10)),
|
|
23
23
|
path TEXT NOT NULL UNIQUE,
|
|
24
24
|
data BLOB NOT NULL,
|
|
25
25
|
metadata BLOB,
|
|
@@ -28,7 +28,7 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
28
28
|
CHECK (is_valid_file_path(path))
|
|
29
29
|
) STRICT;
|
|
30
30
|
|
|
31
|
-
CREATE TABLE IF NOT EXISTS
|
|
31
|
+
CREATE TABLE IF NOT EXISTS file_queue (
|
|
32
32
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
33
33
|
file_id TEXT NOT NULL,
|
|
34
34
|
data_before BLOB,
|
|
@@ -41,18 +41,18 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
41
41
|
|
|
42
42
|
CREATE TRIGGER IF NOT EXISTS file_insert BEFORE INSERT ON file
|
|
43
43
|
BEGIN
|
|
44
|
-
INSERT INTO
|
|
44
|
+
INSERT INTO file_queue(
|
|
45
45
|
file_id, path_after, data_after, metadata_after
|
|
46
46
|
)
|
|
47
47
|
VALUES (
|
|
48
48
|
NEW.id, NEW.path, NEW.data, NEW.metadata
|
|
49
49
|
);
|
|
50
|
-
SELECT
|
|
50
|
+
SELECT triggerFileQueue();
|
|
51
51
|
END;
|
|
52
52
|
|
|
53
53
|
CREATE TRIGGER IF NOT EXISTS file_update BEFORE UPDATE ON file
|
|
54
54
|
BEGIN
|
|
55
|
-
INSERT INTO
|
|
55
|
+
INSERT INTO file_queue(
|
|
56
56
|
file_id,
|
|
57
57
|
path_before, data_before, metadata_before,
|
|
58
58
|
path_after, data_after, metadata_after
|
|
@@ -64,14 +64,14 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
64
64
|
NEW.path, NEW.data, NEW.metadata
|
|
65
65
|
);
|
|
66
66
|
|
|
67
|
-
SELECT
|
|
67
|
+
SELECT triggerFileQueue();
|
|
68
68
|
END;
|
|
69
69
|
|
|
70
70
|
CREATE TRIGGER IF NOT EXISTS file_delete BEFORE DELETE ON file
|
|
71
71
|
BEGIN
|
|
72
|
-
INSERT INTO
|
|
72
|
+
INSERT INTO file_queue(file_id)
|
|
73
73
|
VALUES (OLD.id);
|
|
74
|
-
SELECT
|
|
74
|
+
SELECT triggerFileQueue();
|
|
75
75
|
END;
|
|
76
76
|
|
|
77
77
|
CREATE TABLE IF NOT EXISTS change (
|
|
@@ -144,7 +144,7 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
144
144
|
-- change sets
|
|
145
145
|
|
|
146
146
|
CREATE TABLE IF NOT EXISTS change_set (
|
|
147
|
-
id TEXT PRIMARY KEY DEFAULT (
|
|
147
|
+
id TEXT PRIMARY KEY DEFAULT (nano_id(16))
|
|
148
148
|
) STRICT;
|
|
149
149
|
|
|
150
150
|
CREATE TABLE IF NOT EXISTS change_set_element (
|
|
@@ -165,34 +165,21 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
165
165
|
FOREIGN KEY(change_set_id) REFERENCES change_set(id)
|
|
166
166
|
) STRICT;
|
|
167
167
|
|
|
168
|
-
CREATE TABLE IF NOT EXISTS change_set_label_author (
|
|
169
|
-
label_id TEXT NOT NULL,
|
|
170
|
-
change_set_id TEXT NOT NULL,
|
|
171
|
-
account_id TEXT NOT NULL,
|
|
172
|
-
|
|
173
|
-
PRIMARY KEY(label_id, change_set_id, account_id),
|
|
174
|
-
FOREIGN KEY(label_id, change_set_id) REFERENCES change_set_label(label_id, change_set_id),
|
|
175
|
-
FOREIGN KEY(account_id) REFERENCES account(id)
|
|
176
|
-
) STRICT;
|
|
177
|
-
|
|
178
168
|
-- discussions
|
|
179
169
|
|
|
180
170
|
CREATE TABLE IF NOT EXISTS discussion (
|
|
181
|
-
id TEXT PRIMARY KEY DEFAULT (
|
|
171
|
+
id TEXT PRIMARY KEY DEFAULT (nano_id(12)),
|
|
182
172
|
change_set_id TEXT NOT NULL,
|
|
183
173
|
|
|
184
174
|
FOREIGN KEY(change_set_id) REFERENCES change_set(id)
|
|
185
175
|
) STRICT;
|
|
186
176
|
|
|
187
177
|
CREATE TABLE IF NOT EXISTS comment (
|
|
188
|
-
id TEXT PRIMARY KEY DEFAULT (
|
|
178
|
+
id TEXT PRIMARY KEY DEFAULT (nano_id(14)),
|
|
189
179
|
parent_id TEXT,
|
|
190
180
|
discussion_id TEXT NULL,
|
|
191
|
-
created_at TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
192
181
|
content TEXT NOT NULL,
|
|
193
|
-
created_by TEXT NOT NULL,
|
|
194
182
|
|
|
195
|
-
FOREIGN KEY(created_by) REFERENCES account(id),
|
|
196
183
|
FOREIGN KEY(discussion_id) REFERENCES discussion(id),
|
|
197
184
|
FOREIGN KEY(parent_id) REFERENCES comment(id)
|
|
198
185
|
) STRICT;
|
|
@@ -200,7 +187,7 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
200
187
|
-- labels
|
|
201
188
|
|
|
202
189
|
CREATE TABLE IF NOT EXISTS label (
|
|
203
|
-
id TEXT PRIMARY KEY DEFAULT (
|
|
190
|
+
id TEXT PRIMARY KEY DEFAULT (nano_id(8)),
|
|
204
191
|
|
|
205
192
|
name TEXT NOT NULL UNIQUE -- e.g., 'confirmed', 'reviewed'
|
|
206
193
|
|
|
@@ -214,23 +201,22 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
214
201
|
CREATE TABLE IF NOT EXISTS version (
|
|
215
202
|
id TEXT PRIMARY KEY DEFAULT (uuid_v7()),
|
|
216
203
|
|
|
217
|
-
|
|
218
|
-
--
|
|
219
|
-
-- "anonymous" versiones can ease workflows.
|
|
220
|
-
-- For example, a user can create a version
|
|
221
|
-
-- without a name to experiment with
|
|
222
|
-
-- changes with no mental overhead of
|
|
223
|
-
-- naming the version.
|
|
224
|
-
name TEXT
|
|
204
|
+
name TEXT NOT NULL UNIQUE DEFAULT (human_id())
|
|
225
205
|
) STRICT;
|
|
226
206
|
|
|
227
207
|
CREATE TABLE IF NOT EXISTS version_change (
|
|
228
208
|
version_id TEXT NOT NULL,
|
|
229
209
|
change_id TEXT NOT NULL,
|
|
230
210
|
|
|
211
|
+
entity_id TEXT NOT NULL,
|
|
212
|
+
schema_key TEXT NOT NULL,
|
|
213
|
+
file_id TEXT NOT NULL,
|
|
214
|
+
|
|
231
215
|
PRIMARY KEY (version_id, change_id),
|
|
232
216
|
FOREIGN KEY (version_id) REFERENCES version(id) ON DELETE CASCADE,
|
|
233
|
-
FOREIGN KEY (change_id) REFERENCES change(id) ON DELETE CASCADE
|
|
217
|
+
FOREIGN KEY (change_id, entity_id, schema_key, file_id) REFERENCES change(id, entity_id, schema_key, file_id) ON DELETE CASCADE,
|
|
218
|
+
|
|
219
|
+
UNIQUE (version_id, entity_id, schema_key, file_id)
|
|
234
220
|
) STRICT;
|
|
235
221
|
|
|
236
222
|
CREATE TABLE IF NOT EXISTS version_change_conflict (
|
|
@@ -276,47 +262,8 @@ export function applySchema(args: { sqlite: SqliteDatabase }): SqliteDatabase {
|
|
|
276
262
|
WHERE id = NEW.account_id;
|
|
277
263
|
END;
|
|
278
264
|
|
|
279
|
-
CREATE TEMP TRIGGER IF NOT EXISTS insert_account_if_not_exists_on_change_set_label_author
|
|
280
|
-
BEFORE INSERT ON change_set_label_author
|
|
281
|
-
FOR EACH ROW
|
|
282
|
-
WHEN NEW.account_id NOT IN (SELECT id FROM account) AND NEW.account_id IN (SELECT id FROM temp.active_account)
|
|
283
|
-
BEGIN
|
|
284
|
-
INSERT OR IGNORE INTO account
|
|
285
|
-
SELECT
|
|
286
|
-
*
|
|
287
|
-
FROM active_account
|
|
288
|
-
WHERE id = NEW.account_id;
|
|
289
|
-
END;
|
|
290
|
-
|
|
291
|
-
CREATE TEMP TRIGGER IF NOT EXISTS insert_account_if_not_exists_on_comment
|
|
292
|
-
BEFORE INSERT ON comment
|
|
293
|
-
FOR EACH ROW
|
|
294
|
-
WHEN NEW.created_by NOT IN (SELECT id FROM account) AND NEW.created_by IN (SELECT id FROM temp.active_account)
|
|
295
|
-
BEGIN
|
|
296
|
-
INSERT OR IGNORE INTO account
|
|
297
|
-
SELECT
|
|
298
|
-
*
|
|
299
|
-
FROM active_account
|
|
300
|
-
WHERE id = NEW.created_by;
|
|
301
|
-
END;
|
|
302
|
-
|
|
303
|
-
|
|
304
265
|
`;
|
|
305
266
|
|
|
306
|
-
// CREATE TRIGGER IF NOT EXISTS insert_account_if_not_exists_on_change_set_label_author
|
|
307
|
-
// BEFORE INSERT ON change_set_label_author
|
|
308
|
-
// FOR EACH ROW
|
|
309
|
-
// BEGIN
|
|
310
|
-
// INSERT OR IGNORE INTO account (id, name)
|
|
311
|
-
// VALUES (
|
|
312
|
-
// NEW.account_id,
|
|
313
|
-
// CASE
|
|
314
|
-
// WHEN NEW.account_id LIKE 'anonymous_%' THEN 'anonymous'
|
|
315
|
-
// ELSE NEW.account_id
|
|
316
|
-
// END
|
|
317
|
-
// );
|
|
318
|
-
// END;
|
|
319
|
-
|
|
320
267
|
applyMutationLogDatabaseSchema(args.sqlite);
|
|
321
268
|
|
|
322
269
|
return args.sqlite;
|
|
@@ -28,7 +28,7 @@ test("handles joins", async () => {
|
|
|
28
28
|
const mockFile0: LixFile = {
|
|
29
29
|
id: "file-0",
|
|
30
30
|
path: "/file-0",
|
|
31
|
-
data: new
|
|
31
|
+
data: new Uint8Array(),
|
|
32
32
|
metadata: {},
|
|
33
33
|
};
|
|
34
34
|
const mockChange0 = mockChange({ id: "change-0", file_id: "file-0" });
|
|
@@ -56,7 +56,7 @@ test("does not transform the query or results (json parsing)", async () => {
|
|
|
56
56
|
const mockFile0: LixFile = {
|
|
57
57
|
id: "file-0",
|
|
58
58
|
path: "/file-0",
|
|
59
|
-
data: new
|
|
59
|
+
data: new Uint8Array(),
|
|
60
60
|
metadata: {
|
|
61
61
|
foo: "bar",
|
|
62
62
|
},
|
|
@@ -100,7 +100,7 @@ test("using executeSync with a 'fake async' function should work", async () => {
|
|
|
100
100
|
|
|
101
101
|
const result = await fakeAyncQuery(lix);
|
|
102
102
|
|
|
103
|
-
expect(result).
|
|
103
|
+
expect(result).toMatchObject([{ key: "foo", value: "bar" }]);
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
test("it works with kysely transactions", async () => {
|
|
@@ -7,31 +7,28 @@ import { jsonSha256 } from "../snapshot/json-sha-256.js";
|
|
|
7
7
|
import { sql } from "kysely";
|
|
8
8
|
import { openLixInMemory } from "../lix/open-lix-in-memory.js";
|
|
9
9
|
import { updateChangesInVersion } from "../version/update-changes-in-version.js";
|
|
10
|
+
import { createVersion } from "../version/create-version.js";
|
|
11
|
+
|
|
12
|
+
// file ids are always in the URL of lix apps
|
|
13
|
+
// to increase sharing, the ids should be as short as possible
|
|
14
|
+
//
|
|
15
|
+
// 129 million file creations will lead to a 1% chance of a collision
|
|
16
|
+
//
|
|
17
|
+
// if someone uses lix to handle 129 million files, we can
|
|
18
|
+
// increase the length of the id :D
|
|
19
|
+
test("file ids should default to nano_id(10)", async () => {
|
|
20
|
+
const lix = await openLixInMemory({});
|
|
10
21
|
|
|
11
|
-
|
|
12
|
-
const sqlite = await createInMemoryDatabase({
|
|
13
|
-
readOnly: false,
|
|
14
|
-
});
|
|
15
|
-
const db = initDb({ sqlite });
|
|
16
|
-
|
|
17
|
-
// init the trigger function (usually defined by lix only)
|
|
18
|
-
sqlite.createFunction({
|
|
19
|
-
name: "triggerChangeQueue",
|
|
20
|
-
arity: 0,
|
|
21
|
-
// @ts-expect-error - dynamic function
|
|
22
|
-
xFunc: () => {},
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const file = await db
|
|
22
|
+
const file = await lix.db
|
|
26
23
|
.insertInto("file")
|
|
27
24
|
.values({
|
|
28
|
-
path: "/mock",
|
|
25
|
+
path: "/mock.txt",
|
|
29
26
|
data: new Uint8Array(),
|
|
30
27
|
})
|
|
31
28
|
.returningAll()
|
|
32
29
|
.executeTakeFirstOrThrow();
|
|
33
30
|
|
|
34
|
-
expect(
|
|
31
|
+
expect(file.id.length).toBe(10);
|
|
35
32
|
});
|
|
36
33
|
|
|
37
34
|
test("change ids should default to uuid", async () => {
|
|
@@ -142,7 +139,7 @@ test("files should be able to have metadata", async () => {
|
|
|
142
139
|
const db = initDb({ sqlite });
|
|
143
140
|
|
|
144
141
|
sqlite.createFunction({
|
|
145
|
-
name: "
|
|
142
|
+
name: "triggerFileQueue",
|
|
146
143
|
arity: 0,
|
|
147
144
|
// @ts-expect-error - dynamic function
|
|
148
145
|
xFunc: () => {
|
|
@@ -243,6 +240,98 @@ test("change set items must be unique", async () => {
|
|
|
243
240
|
);
|
|
244
241
|
});
|
|
245
242
|
|
|
243
|
+
// 8B IDs needed, in order to have a 1% probability of at least one collision.
|
|
244
|
+
test("discussion.id are nano_id(12)", async () => {
|
|
245
|
+
const sqlite = await createInMemoryDatabase({
|
|
246
|
+
readOnly: false,
|
|
247
|
+
});
|
|
248
|
+
const db = initDb({ sqlite });
|
|
249
|
+
|
|
250
|
+
const changeSet = await db
|
|
251
|
+
.insertInto("change_set")
|
|
252
|
+
.defaultValues()
|
|
253
|
+
.returningAll()
|
|
254
|
+
.executeTakeFirstOrThrow();
|
|
255
|
+
|
|
256
|
+
const discussion = await db
|
|
257
|
+
.insertInto("discussion")
|
|
258
|
+
.values({
|
|
259
|
+
change_set_id: changeSet.id,
|
|
260
|
+
})
|
|
261
|
+
.returningAll()
|
|
262
|
+
.executeTakeFirstOrThrow();
|
|
263
|
+
|
|
264
|
+
expect(discussion.id.length).toBe(12);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// 499B IDs needed, in order to have a 1% probability of at least one collision.
|
|
268
|
+
test("comment.id are nano_id(14)", async () => {
|
|
269
|
+
const sqlite = await createInMemoryDatabase({
|
|
270
|
+
readOnly: false,
|
|
271
|
+
});
|
|
272
|
+
const db = initDb({ sqlite });
|
|
273
|
+
|
|
274
|
+
const changeSet = await db
|
|
275
|
+
.insertInto("change_set")
|
|
276
|
+
.defaultValues()
|
|
277
|
+
.returningAll()
|
|
278
|
+
.executeTakeFirstOrThrow();
|
|
279
|
+
|
|
280
|
+
const discussion = await db
|
|
281
|
+
.insertInto("discussion")
|
|
282
|
+
.values({
|
|
283
|
+
change_set_id: changeSet.id,
|
|
284
|
+
})
|
|
285
|
+
.returningAll()
|
|
286
|
+
.executeTakeFirstOrThrow();
|
|
287
|
+
|
|
288
|
+
const comment = await db
|
|
289
|
+
.insertInto("comment")
|
|
290
|
+
.values({
|
|
291
|
+
discussion_id: discussion.id,
|
|
292
|
+
content: "mock",
|
|
293
|
+
})
|
|
294
|
+
.returningAll()
|
|
295
|
+
.executeTakeFirstOrThrow();
|
|
296
|
+
|
|
297
|
+
expect(comment.id.length).toBe(14);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// 30T IDs needed, in order to have a 1% probability of at least one collision
|
|
301
|
+
test("change_set.id are nano_id(16)", async () => {
|
|
302
|
+
const sqlite = await createInMemoryDatabase({
|
|
303
|
+
readOnly: false,
|
|
304
|
+
});
|
|
305
|
+
const db = initDb({ sqlite });
|
|
306
|
+
|
|
307
|
+
const changeSet = await db
|
|
308
|
+
.insertInto("change_set")
|
|
309
|
+
.defaultValues()
|
|
310
|
+
.returningAll()
|
|
311
|
+
.executeTakeFirstOrThrow();
|
|
312
|
+
|
|
313
|
+
expect(changeSet.id.length).toBe(16);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// 2M IDs needed, in order to have a 1% probability of at least one collision.
|
|
317
|
+
// it is assumed that creating 2 million labels is ... unlikely
|
|
318
|
+
test("label.id is nano_id(8)", async () => {
|
|
319
|
+
const sqlite = await createInMemoryDatabase({
|
|
320
|
+
readOnly: false,
|
|
321
|
+
});
|
|
322
|
+
const db = initDb({ sqlite });
|
|
323
|
+
|
|
324
|
+
const label = await db
|
|
325
|
+
.insertInto("label")
|
|
326
|
+
.values({
|
|
327
|
+
name: "mock",
|
|
328
|
+
})
|
|
329
|
+
.returningAll()
|
|
330
|
+
.executeTakeFirstOrThrow();
|
|
331
|
+
|
|
332
|
+
expect(label.id.length).toBe(8);
|
|
333
|
+
});
|
|
334
|
+
|
|
246
335
|
test("creating multiple discussions for one change set should be possible", async () => {
|
|
247
336
|
const sqlite = await createInMemoryDatabase({
|
|
248
337
|
readOnly: false,
|
|
@@ -337,7 +426,7 @@ test("invalid file paths should be rejected", async () => {
|
|
|
337
426
|
|
|
338
427
|
// init the trigger function (usually defined by lix only)
|
|
339
428
|
sqlite.createFunction({
|
|
340
|
-
name: "
|
|
429
|
+
name: "triggerFileQueue",
|
|
341
430
|
arity: 0,
|
|
342
431
|
// @ts-expect-error - dynamic function
|
|
343
432
|
xFunc: () => {},
|
|
@@ -482,3 +571,58 @@ test("deleting a version cascades to version changes", async () => {
|
|
|
482
571
|
|
|
483
572
|
expect(versionChangesAfterDelete).toHaveLength(0);
|
|
484
573
|
});
|
|
574
|
+
|
|
575
|
+
test("version_change must have a unique entity_id, file_id, version_id, and schema_id", async () => {
|
|
576
|
+
const lix = await openLixInMemory({});
|
|
577
|
+
|
|
578
|
+
const version0 = await createVersion({ lix, name: "version0" });
|
|
579
|
+
const version1 = await createVersion({ lix, name: "version1" });
|
|
580
|
+
|
|
581
|
+
const mockChanges = [
|
|
582
|
+
mockChange({ entity_id: "mock0", file_id: "file0", schema_key: "file" }),
|
|
583
|
+
] as const;
|
|
584
|
+
|
|
585
|
+
await lix.db.insertInto("change").values(mockChanges).execute();
|
|
586
|
+
|
|
587
|
+
const versionChange = {
|
|
588
|
+
change_id: mockChanges[0].id,
|
|
589
|
+
file_id: mockChanges[0].file_id,
|
|
590
|
+
entity_id: mockChanges[0].entity_id,
|
|
591
|
+
schema_key: mockChanges[0].schema_key,
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
await lix.db
|
|
595
|
+
.insertInto("version_change")
|
|
596
|
+
.values({ ...versionChange, version_id: version0.id })
|
|
597
|
+
.execute();
|
|
598
|
+
|
|
599
|
+
// inserting the same change again should throw
|
|
600
|
+
await expect(
|
|
601
|
+
lix.db
|
|
602
|
+
.insertInto("version_change")
|
|
603
|
+
.values({ ...versionChange, version_id: version0.id })
|
|
604
|
+
.execute()
|
|
605
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
606
|
+
`[SQLite3Error: SQLITE_CONSTRAINT_UNIQUE: sqlite3 result code 2067: UNIQUE constraint failed: version_change.version_id, version_change.entity_id, version_change.schema_key, version_change.file_id]`
|
|
607
|
+
);
|
|
608
|
+
|
|
609
|
+
// insert into version 1 should work
|
|
610
|
+
await lix.db
|
|
611
|
+
.insertInto("version_change")
|
|
612
|
+
.values({ ...versionChange, version_id: version1.id })
|
|
613
|
+
.execute();
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
test("versions have a unique and default human readable name", async () => {
|
|
617
|
+
const lix = await openLixInMemory({});
|
|
618
|
+
|
|
619
|
+
const version0 = await createVersion({ lix });
|
|
620
|
+
const version1 = await createVersion({ lix });
|
|
621
|
+
|
|
622
|
+
expect(version0.name).not.toBe(version1.name);
|
|
623
|
+
|
|
624
|
+
await expect(
|
|
625
|
+
createVersion({ lix, name: version0.name }),
|
|
626
|
+
"version.name is unique"
|
|
627
|
+
).rejects.toThrow();
|
|
628
|
+
});
|
package/src/database/init-db.ts
CHANGED
|
@@ -8,7 +8,9 @@ import { jsonSha256 } from "../snapshot/json-sha-256.js";
|
|
|
8
8
|
import { ParseJsonBPluginV1 } from "./kysely-plugin/parse-jsonb-plugin-v1.js";
|
|
9
9
|
import { SerializeJsonBPlugin } from "./kysely-plugin/serialize-jsonb-plugin.js";
|
|
10
10
|
import { createSession } from "./mutation-log/lix-session.js";
|
|
11
|
-
import {
|
|
11
|
+
import { applyOwnChangeControlTriggers } from "../own-change-control/database-triggers.js";
|
|
12
|
+
import { humanId } from "human-id";
|
|
13
|
+
import { nanoid } from "./nano-id.js";
|
|
12
14
|
|
|
13
15
|
export function initDb(args: {
|
|
14
16
|
sqlite: SqliteDatabase;
|
|
@@ -23,7 +25,7 @@ export function initDb(args: {
|
|
|
23
25
|
ParseJsonBPluginV1({
|
|
24
26
|
// jsonb columns
|
|
25
27
|
file: ["metadata"],
|
|
26
|
-
|
|
28
|
+
file_queue: ["metadata_before", "metadata_after"],
|
|
27
29
|
snapshot: ["content"],
|
|
28
30
|
mutation_log: ["row_id"],
|
|
29
31
|
}),
|
|
@@ -32,7 +34,7 @@ export function initDb(args: {
|
|
|
32
34
|
});
|
|
33
35
|
|
|
34
36
|
// need to apply it here because db object needs to be available
|
|
35
|
-
|
|
37
|
+
applyOwnChangeControlTriggers(args.sqlite, db);
|
|
36
38
|
return db;
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -91,4 +93,19 @@ function initFunctions(args: { sqlite: SqliteDatabase }) {
|
|
|
91
93
|
arity: 0,
|
|
92
94
|
xFunc: () => lixSession.sessionClockTick(),
|
|
93
95
|
});
|
|
96
|
+
|
|
97
|
+
args.sqlite.createFunction({
|
|
98
|
+
name: "human_id",
|
|
99
|
+
arity: 0,
|
|
100
|
+
xFunc: () => humanId({ separator: "-", capitalize: false }),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
args.sqlite.createFunction({
|
|
104
|
+
name: "nano_id",
|
|
105
|
+
arity: 1,
|
|
106
|
+
// @ts-expect-error - not sure why this is not working
|
|
107
|
+
xFunc: (_ctx: number, length: number) => {
|
|
108
|
+
return nanoid(length);
|
|
109
|
+
},
|
|
110
|
+
});
|
|
94
111
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { type KyselyPlugin } from "kysely";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createInMemoryDatabase,
|
|
4
|
+
type SqliteDatabase,
|
|
5
|
+
} from "sqlite-wasm-kysely";
|
|
3
6
|
|
|
4
7
|
// workaround for v1. v2 doesn't need to transform
|
|
5
8
|
// jsonb columns during runtime
|
|
6
|
-
|
|
9
|
+
let sqlite: SqliteDatabase;
|
|
7
10
|
|
|
8
11
|
export function ParseJsonBPluginV1(
|
|
9
12
|
jsonbColumns: Record<string, string[]>
|
|
@@ -14,6 +17,10 @@ export function ParseJsonBPluginV1(
|
|
|
14
17
|
|
|
15
18
|
return {
|
|
16
19
|
transformResult: async (args) => {
|
|
20
|
+
if (!sqlite) {
|
|
21
|
+
sqlite = await createInMemoryDatabase({});
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
for (const row of args.result.rows) {
|
|
18
25
|
for (const col of jsonColumnNames) {
|
|
19
26
|
if (!row[col]) {
|
|
@@ -14,7 +14,7 @@ export const tablesByDepencies: string[] = [
|
|
|
14
14
|
"change",
|
|
15
15
|
|
|
16
16
|
// Depends on: file
|
|
17
|
-
"
|
|
17
|
+
"file_queue",
|
|
18
18
|
// Depends on: change
|
|
19
19
|
"change_author",
|
|
20
20
|
// Depends on: change
|
|
@@ -27,8 +27,6 @@ export const tablesByDepencies: string[] = [
|
|
|
27
27
|
"change_set_element",
|
|
28
28
|
// Depends on: label, change_set
|
|
29
29
|
"change_set_label",
|
|
30
|
-
// Depends on: change_set_label
|
|
31
|
-
"change_set_label_author",
|
|
32
30
|
//Depends on: change_set
|
|
33
31
|
"discussion",
|
|
34
32
|
// Depends on: account, discussion, comment
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { _nanoIdAlphabet, nanoid } from "./nano-id.js";
|
|
3
|
+
|
|
4
|
+
test("length is obeyed", () => {
|
|
5
|
+
const id = nanoid(10);
|
|
6
|
+
expect(id.length).toBe(10);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("the alphabet does not contain underscores `_` because they are not URL safe", () => {
|
|
10
|
+
expect(_nanoIdAlphabet).not.toContain("_");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("the alphabet does not contain dashes `-` because they break selecting the ID from the URL in the browser", () => {
|
|
14
|
+
expect(_nanoIdAlphabet).not.toContain("-");
|
|
15
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code taken from the [nanoid](https://github.com/ai/nanoid/blob/main/index.browser.js)
|
|
3
|
+
* browser implementation. The code is licensed under the MIT license.
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const random = (bytes: any) => crypto.getRandomValues(new Uint8Array(bytes));
|
|
8
|
+
|
|
9
|
+
const customRandom = (
|
|
10
|
+
alphabet: string,
|
|
11
|
+
defaultSize: number,
|
|
12
|
+
getRandom: any
|
|
13
|
+
) => {
|
|
14
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
|
15
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
|
16
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
|
17
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
|
18
|
+
// `Math.clz32` is not used, because it is not available in browsers.
|
|
19
|
+
const mask = (2 << Math.log2(alphabet.length - 1)) - 1;
|
|
20
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
|
21
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
|
22
|
+
// the random bytes redundancy has to be satisfied.
|
|
23
|
+
|
|
24
|
+
// Note: every hardware random generator call is performance expensive,
|
|
25
|
+
// because the system call for entropy collection takes a lot of time.
|
|
26
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
|
27
|
+
|
|
28
|
+
// Next, a step determines how many random bytes to generate.
|
|
29
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
|
30
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
|
31
|
+
// according to benchmarks).
|
|
32
|
+
|
|
33
|
+
// `-~f => Math.ceil(f)` if f is a float
|
|
34
|
+
// `-~i => i + 1` if i is an integer
|
|
35
|
+
const step = -~((1.6 * mask * defaultSize) / alphabet.length);
|
|
36
|
+
|
|
37
|
+
return (size = defaultSize) => {
|
|
38
|
+
let id = "";
|
|
39
|
+
while (true) {
|
|
40
|
+
const bytes = getRandom(step);
|
|
41
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
|
42
|
+
let j = step | 0;
|
|
43
|
+
while (j--) {
|
|
44
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
|
45
|
+
id += alphabet[bytes[j] & mask] || "";
|
|
46
|
+
if (id.length >= size) return id;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const customAlphabet = (alphabet: string, size = 21) =>
|
|
53
|
+
customRandom(alphabet, size | 0, random);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Uses every character from nano id except for the `-` and `_` character.
|
|
57
|
+
*
|
|
58
|
+
* - Underscore `_` is not URL safe https://github.com/ai/nanoid/issues/347.
|
|
59
|
+
* - Dash `-` breaks selecting the ID from the URL in the browser.
|
|
60
|
+
*/
|
|
61
|
+
export const _nanoIdAlphabet =
|
|
62
|
+
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generate secure URL-friendly unique ID.
|
|
66
|
+
*
|
|
67
|
+
* Use https://zelark.github.io/nano-id-cc/ to calculate the length
|
|
68
|
+
* of the ID for the use case with the alphabet provided in the
|
|
69
|
+
* implementation.
|
|
70
|
+
*/
|
|
71
|
+
export const nanoid: (size?: number) => string =
|
|
72
|
+
customAlphabet(_nanoIdAlphabet);
|