velocious 1.0.430 → 1.0.431
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/bin/velocious.js +48 -0
- package/build/bin/velocious.js +39 -34
- package/build/index.js +1 -2
- package/build/src/application.js +214 -187
- package/build/src/authorization/ability.d.ts +24 -23
- package/build/src/authorization/ability.d.ts.map +1 -1
- package/build/src/authorization/ability.js +300 -252
- package/build/src/authorization/base-resource.d.ts +20 -26
- package/build/src/authorization/base-resource.d.ts.map +1 -1
- package/build/src/authorization/base-resource.js +136 -118
- package/build/src/background-jobs/client.js +47 -43
- package/build/src/background-jobs/cron-expression.js +166 -127
- package/build/src/background-jobs/forked-runner-child.js +47 -37
- package/build/src/background-jobs/job-record.js +10 -8
- package/build/src/background-jobs/job-registry.js +84 -72
- package/build/src/background-jobs/job-runner.js +81 -74
- package/build/src/background-jobs/job.js +72 -62
- package/build/src/background-jobs/json-socket.js +70 -65
- package/build/src/background-jobs/main.js +900 -841
- package/build/src/background-jobs/normalize-error.js +11 -12
- package/build/src/background-jobs/scheduler.js +247 -205
- package/build/src/background-jobs/socket-request.js +65 -60
- package/build/src/background-jobs/status-reporter.js +96 -86
- package/build/src/background-jobs/store.js +980 -862
- package/build/src/background-jobs/types.js +3 -2
- package/build/src/background-jobs/web/authorization.js +50 -38
- package/build/src/background-jobs/web/controller.js +268 -232
- package/build/src/background-jobs/web/index.js +40 -36
- package/build/src/background-jobs/web/path-matcher.js +48 -45
- package/build/src/background-jobs/web/registry.js +14 -9
- package/build/src/background-jobs/worker.js +639 -585
- package/build/src/beacon/client.js +293 -264
- package/build/src/beacon/in-process-broker.js +25 -20
- package/build/src/beacon/in-process-client.js +116 -104
- package/build/src/beacon/server.js +126 -110
- package/build/src/beacon/types.js +8 -2
- package/build/src/cli/base-command.js +57 -49
- package/build/src/cli/browser-cli.js +42 -37
- package/build/src/cli/commands/background-jobs-main.js +5 -5
- package/build/src/cli/commands/background-jobs-runner.js +5 -5
- package/build/src/cli/commands/background-jobs-worker.js +5 -5
- package/build/src/cli/commands/beacon.js +5 -5
- package/build/src/cli/commands/console.js +10 -10
- package/build/src/cli/commands/db/base-command.js +76 -71
- package/build/src/cli/commands/db/create.js +61 -53
- package/build/src/cli/commands/db/drop.js +71 -62
- package/build/src/cli/commands/db/migrate.js +15 -13
- package/build/src/cli/commands/db/reset.js +19 -16
- package/build/src/cli/commands/db/rollback.js +13 -12
- package/build/src/cli/commands/db/schema/dump.js +9 -9
- package/build/src/cli/commands/db/schema/load.js +9 -9
- package/build/src/cli/commands/db/seed.js +9 -9
- package/build/src/cli/commands/db/tenants/check.js +35 -32
- package/build/src/cli/commands/db/tenants/create.js +29 -26
- package/build/src/cli/commands/db/tenants/migrate.js +44 -40
- package/build/src/cli/commands/destroy/migration.js +5 -5
- package/build/src/cli/commands/generate/base-models.js +5 -5
- package/build/src/cli/commands/generate/frontend-models.js +9 -9
- package/build/src/cli/commands/generate/migration.js +5 -5
- package/build/src/cli/commands/generate/model.js +5 -5
- package/build/src/cli/commands/init.js +9 -7
- package/build/src/cli/commands/routes.js +6 -6
- package/build/src/cli/commands/run-script.js +9 -9
- package/build/src/cli/commands/runner.js +9 -9
- package/build/src/cli/commands/server.js +6 -6
- package/build/src/cli/commands/test.js +7 -6
- package/build/src/cli/index.js +141 -127
- package/build/src/cli/tenant-database-command-helper.js +185 -154
- package/build/src/cli/use-browser-cli.js +20 -15
- package/build/src/configuration-resolver.js +54 -47
- package/build/src/configuration-types.d.ts +21 -2
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +60 -3
- package/build/src/configuration.js +2547 -2240
- package/build/src/controller.js +407 -363
- package/build/src/current-configuration.js +12 -9
- package/build/src/current.js +75 -70
- package/build/src/database/annotations-async-hooks.js +22 -16
- package/build/src/database/annotations.js +18 -12
- package/build/src/database/drivers/base-column.js +179 -155
- package/build/src/database/drivers/base-columns-index.js +78 -69
- package/build/src/database/drivers/base-foreign-key.js +101 -89
- package/build/src/database/drivers/base-table.js +149 -124
- package/build/src/database/drivers/base.js +1489 -1306
- package/build/src/database/drivers/mssql/column.js +50 -39
- package/build/src/database/drivers/mssql/columns-index.js +3 -2
- package/build/src/database/drivers/mssql/connect-connection.js +9 -11
- package/build/src/database/drivers/mssql/foreign-key.js +9 -8
- package/build/src/database/drivers/mssql/index.js +587 -507
- package/build/src/database/drivers/mssql/options.js +75 -68
- package/build/src/database/drivers/mssql/query-parser.js +3 -2
- package/build/src/database/drivers/mssql/sql/alter-table.js +2 -2
- package/build/src/database/drivers/mssql/sql/create-database.js +31 -24
- package/build/src/database/drivers/mssql/sql/create-index.js +2 -2
- package/build/src/database/drivers/mssql/sql/create-table.js +2 -2
- package/build/src/database/drivers/mssql/sql/delete.js +16 -14
- package/build/src/database/drivers/mssql/sql/drop-database.js +31 -24
- package/build/src/database/drivers/mssql/sql/drop-table.js +2 -2
- package/build/src/database/drivers/mssql/sql/insert.js +2 -2
- package/build/src/database/drivers/mssql/sql/update.js +28 -24
- package/build/src/database/drivers/mssql/sql/upsert.js +20 -18
- package/build/src/database/drivers/mssql/structure-sql.js +114 -102
- package/build/src/database/drivers/mssql/table.js +96 -81
- package/build/src/database/drivers/mysql/column.js +92 -75
- package/build/src/database/drivers/mysql/columns-index.js +19 -16
- package/build/src/database/drivers/mysql/foreign-key.js +9 -8
- package/build/src/database/drivers/mysql/index.js +457 -396
- package/build/src/database/drivers/mysql/options.js +30 -26
- package/build/src/database/drivers/mysql/query-parser.js +3 -2
- package/build/src/database/drivers/mysql/query.js +29 -26
- package/build/src/database/drivers/mysql/sql/alter-table.js +3 -2
- package/build/src/database/drivers/mysql/sql/create-database.js +28 -23
- package/build/src/database/drivers/mysql/sql/create-index.js +3 -2
- package/build/src/database/drivers/mysql/sql/create-table.js +3 -2
- package/build/src/database/drivers/mysql/sql/delete.js +17 -14
- package/build/src/database/drivers/mysql/sql/drop-database.js +3 -2
- package/build/src/database/drivers/mysql/sql/drop-table.js +3 -2
- package/build/src/database/drivers/mysql/sql/insert.js +3 -2
- package/build/src/database/drivers/mysql/sql/update.js +29 -24
- package/build/src/database/drivers/mysql/sql/upsert.js +10 -8
- package/build/src/database/drivers/mysql/structure-sql.js +88 -79
- package/build/src/database/drivers/mysql/table.js +98 -83
- package/build/src/database/drivers/pgsql/column.js +72 -56
- package/build/src/database/drivers/pgsql/columns-index.js +3 -2
- package/build/src/database/drivers/pgsql/foreign-key.js +9 -8
- package/build/src/database/drivers/pgsql/index.js +438 -377
- package/build/src/database/drivers/pgsql/options.js +28 -25
- package/build/src/database/drivers/pgsql/query-parser.js +3 -2
- package/build/src/database/drivers/pgsql/sql/alter-table.js +3 -2
- package/build/src/database/drivers/pgsql/sql/create-database.js +23 -19
- package/build/src/database/drivers/pgsql/sql/create-index.js +3 -2
- package/build/src/database/drivers/pgsql/sql/create-table.js +3 -2
- package/build/src/database/drivers/pgsql/sql/delete.js +17 -14
- package/build/src/database/drivers/pgsql/sql/drop-database.js +3 -2
- package/build/src/database/drivers/pgsql/sql/drop-table.js +3 -2
- package/build/src/database/drivers/pgsql/sql/insert.js +3 -2
- package/build/src/database/drivers/pgsql/sql/update.js +29 -24
- package/build/src/database/drivers/pgsql/sql/upsert.js +11 -9
- package/build/src/database/drivers/pgsql/structure-sql.js +120 -108
- package/build/src/database/drivers/pgsql/table.js +77 -60
- package/build/src/database/drivers/sqlite/base.js +478 -405
- package/build/src/database/drivers/sqlite/column.js +69 -54
- package/build/src/database/drivers/sqlite/columns-index.js +27 -22
- package/build/src/database/drivers/sqlite/connection-sql-js.js +42 -35
- package/build/src/database/drivers/sqlite/foreign-key.js +21 -18
- package/build/src/database/drivers/sqlite/index.js +373 -330
- package/build/src/database/drivers/sqlite/index.native.js +64 -55
- package/build/src/database/drivers/sqlite/index.web.js +87 -69
- package/build/src/database/drivers/sqlite/options.js +28 -25
- package/build/src/database/drivers/sqlite/query-parser.js +3 -2
- package/build/src/database/drivers/sqlite/query.js +24 -21
- package/build/src/database/drivers/sqlite/query.native.js +25 -20
- package/build/src/database/drivers/sqlite/query.web.js +37 -30
- package/build/src/database/drivers/sqlite/sql/alter-table.js +179 -159
- package/build/src/database/drivers/sqlite/sql/create-index.js +3 -2
- package/build/src/database/drivers/sqlite/sql/create-table.js +3 -2
- package/build/src/database/drivers/sqlite/sql/delete.js +22 -17
- package/build/src/database/drivers/sqlite/sql/drop-table.js +3 -2
- package/build/src/database/drivers/sqlite/sql/insert.js +3 -2
- package/build/src/database/drivers/sqlite/sql/update.js +29 -24
- package/build/src/database/drivers/sqlite/sql/upsert.js +11 -9
- package/build/src/database/drivers/sqlite/structure-sql.js +52 -49
- package/build/src/database/drivers/sqlite/table-rebuilder.js +75 -62
- package/build/src/database/drivers/sqlite/table.js +125 -102
- package/build/src/database/drivers/structure-sql/utils.js +17 -14
- package/build/src/database/handler.js +10 -9
- package/build/src/database/initializer-from-require-context.js +87 -76
- package/build/src/database/migration/index.js +395 -332
- package/build/src/database/migrator/files-finder.js +50 -40
- package/build/src/database/migrator/types.js +30 -2
- package/build/src/database/migrator.js +526 -454
- package/build/src/database/pool/async-tracked-multi-connection.js +1147 -997
- package/build/src/database/pool/base-methods-forward.js +43 -40
- package/build/src/database/pool/base.js +343 -298
- package/build/src/database/pool/single-multi-use.js +110 -93
- package/build/src/database/query/alter-table-base.js +99 -84
- package/build/src/database/query/base.js +46 -39
- package/build/src/database/query/create-database-base.js +30 -25
- package/build/src/database/query/create-index-base.js +94 -75
- package/build/src/database/query/create-table-base.js +193 -151
- package/build/src/database/query/delete-base.js +16 -14
- package/build/src/database/query/drop-database-base.js +28 -23
- package/build/src/database/query/drop-table-base.js +53 -42
- package/build/src/database/query/from-base.js +33 -30
- package/build/src/database/query/from-plain.js +13 -11
- package/build/src/database/query/from-table.js +15 -13
- package/build/src/database/query/index.js +472 -410
- package/build/src/database/query/insert-base.js +164 -143
- package/build/src/database/query/join-base.js +40 -35
- package/build/src/database/query/join-object.js +153 -128
- package/build/src/database/query/join-plain.js +15 -13
- package/build/src/database/query/join-tracker.js +90 -76
- package/build/src/database/query/model-class-query.js +1370 -1134
- package/build/src/database/query/order-base.js +30 -27
- package/build/src/database/query/order-column.js +53 -44
- package/build/src/database/query/order-plain.js +24 -20
- package/build/src/database/query/preloader/belongs-to.js +258 -210
- package/build/src/database/query/preloader/ensure-model-class-initialized.js +9 -8
- package/build/src/database/query/preloader/has-many.js +301 -240
- package/build/src/database/query/preloader/has-one.js +117 -91
- package/build/src/database/query/preloader/selection.js +129 -117
- package/build/src/database/query/preloader.js +185 -160
- package/build/src/database/query/query-data.js +201 -157
- package/build/src/database/query/select-base.js +27 -25
- package/build/src/database/query/select-plain.js +15 -13
- package/build/src/database/query/select-table-and-column.js +25 -21
- package/build/src/database/query/update-base.js +38 -35
- package/build/src/database/query/upsert-base.js +100 -93
- package/build/src/database/query/where-base.js +35 -32
- package/build/src/database/query/where-combinator.d.ts.map +1 -1
- package/build/src/database/query/where-combinator.js +28 -26
- package/build/src/database/query/where-hash.js +68 -61
- package/build/src/database/query/where-model-class-hash.js +469 -414
- package/build/src/database/query/where-not.js +20 -18
- package/build/src/database/query/where-plain.js +17 -15
- package/build/src/database/query/with-count.js +159 -125
- package/build/src/database/query-parser/base-query-parser.js +37 -32
- package/build/src/database/query-parser/from-parser.js +45 -36
- package/build/src/database/query-parser/group-parser.js +50 -42
- package/build/src/database/query-parser/joins-parser.js +33 -28
- package/build/src/database/query-parser/limit-parser.js +70 -67
- package/build/src/database/query-parser/options.js +82 -75
- package/build/src/database/query-parser/order-parser.js +40 -36
- package/build/src/database/query-parser/select-parser.js +60 -49
- package/build/src/database/query-parser/where-parser.js +41 -36
- package/build/src/database/record/acts-as-list.js +273 -235
- package/build/src/database/record/attachments/download.js +45 -44
- package/build/src/database/record/attachments/handle.js +161 -141
- package/build/src/database/record/attachments/normalize-input.js +138 -128
- package/build/src/database/record/attachments/storage-drivers/filesystem.js +91 -77
- package/build/src/database/record/attachments/storage-drivers/native.js +121 -112
- package/build/src/database/record/attachments/storage-drivers/s3.js +208 -177
- package/build/src/database/record/attachments/store.d.ts +1 -1
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +540 -468
- package/build/src/database/record/index.d.ts +17 -15
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +3894 -3361
- package/build/src/database/record/instance-relationships/base.js +268 -234
- package/build/src/database/record/instance-relationships/belongs-to.js +73 -58
- package/build/src/database/record/instance-relationships/has-many.js +264 -225
- package/build/src/database/record/instance-relationships/has-one.js +105 -85
- package/build/src/database/record/record-not-found-error.js +2 -3
- package/build/src/database/record/relationships/base.d.ts +2 -2
- package/build/src/database/record/relationships/base.d.ts.map +1 -1
- package/build/src/database/record/relationships/base.js +167 -145
- package/build/src/database/record/relationships/belongs-to.js +51 -44
- package/build/src/database/record/relationships/has-many.js +40 -32
- package/build/src/database/record/relationships/has-one.js +40 -32
- package/build/src/database/record/state-machine.js +208 -156
- package/build/src/database/record/user-module.js +38 -32
- package/build/src/database/record/validators/base.js +24 -22
- package/build/src/database/record/validators/format.js +46 -36
- package/build/src/database/record/validators/presence.js +20 -18
- package/build/src/database/record/validators/uniqueness.js +117 -99
- package/build/src/database/table-data/index.js +231 -199
- package/build/src/database/table-data/table-column.js +382 -338
- package/build/src/database/table-data/table-foreign-key.js +66 -57
- package/build/src/database/table-data/table-index.js +36 -29
- package/build/src/database/table-data/table-reference.js +10 -10
- package/build/src/database/use-database.js +40 -32
- package/build/src/environment-handlers/base.js +544 -484
- package/build/src/environment-handlers/browser.js +294 -241
- package/build/src/environment-handlers/node/cli/commands/background-jobs-main.js +19 -16
- package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +21 -18
- package/build/src/environment-handlers/node/cli/commands/background-jobs-worker.js +29 -22
- package/build/src/environment-handlers/node/cli/commands/beacon.js +19 -16
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +15 -14
- package/build/src/environment-handlers/node/cli/commands/console.js +120 -99
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +39 -34
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +63 -57
- package/build/src/environment-handlers/node/cli/commands/db/seed.js +63 -51
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +40 -32
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +353 -298
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +844 -729
- package/build/src/environment-handlers/node/cli/commands/generate/migration.js +38 -34
- package/build/src/environment-handlers/node/cli/commands/generate/model.js +38 -34
- package/build/src/environment-handlers/node/cli/commands/init.js +61 -56
- package/build/src/environment-handlers/node/cli/commands/routes.js +59 -51
- package/build/src/environment-handlers/node/cli/commands/run-script.js +68 -54
- package/build/src/environment-handlers/node/cli/commands/runner.js +74 -56
- package/build/src/environment-handlers/node/cli/commands/server.js +106 -93
- package/build/src/environment-handlers/node/cli/commands/test.js +113 -97
- package/build/src/environment-handlers/node.js +874 -753
- package/build/src/error-logger.js +21 -22
- package/build/src/frontend-model-controller.d.ts +6 -6
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +3288 -2788
- package/build/src/frontend-model-resource/base-resource.d.ts +18 -17
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +869 -759
- package/build/src/frontend-models/base.d.ts +19 -12
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +3602 -3114
- package/build/src/frontend-models/clear-pending-debounced-callback.js +8 -7
- package/build/src/frontend-models/event-hook-models.js +21 -16
- package/build/src/frontend-models/model-registry.js +11 -9
- package/build/src/frontend-models/outgoing-event-buffer.js +17 -10
- package/build/src/frontend-models/preloader.d.ts +6 -6
- package/build/src/frontend-models/preloader.d.ts.map +1 -1
- package/build/src/frontend-models/preloader.js +149 -131
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +1855 -1560
- package/build/src/frontend-models/resource-config-validation.js +37 -27
- package/build/src/frontend-models/resource-definition.js +288 -234
- package/build/src/frontend-models/transport-serialization.js +266 -203
- package/build/src/frontend-models/use-created-event.js +7 -5
- package/build/src/frontend-models/use-destroyed-event.js +93 -80
- package/build/src/frontend-models/use-model-class-event.js +91 -79
- package/build/src/frontend-models/use-updated-event.js +97 -84
- package/build/src/frontend-models/websocket-channel.js +441 -381
- package/build/src/frontend-models/websocket-publishers.js +173 -140
- package/build/src/http-client/header.js +14 -13
- package/build/src/http-client/index.js +132 -116
- package/build/src/http-client/request.js +87 -71
- package/build/src/http-client/response.js +140 -122
- package/build/src/http-client/websocket-client.js +17 -15
- package/build/src/http-server/client/index.js +465 -409
- package/build/src/http-server/client/params-to-object.js +135 -124
- package/build/src/http-server/client/request-buffer/form-data-part.js +132 -111
- package/build/src/http-server/client/request-buffer/header.js +16 -15
- package/build/src/http-server/client/request-buffer/index.js +506 -446
- package/build/src/http-server/client/request-parser.js +186 -163
- package/build/src/http-server/client/request-runner.js +259 -226
- package/build/src/http-server/client/request-timing.js +151 -132
- package/build/src/http-server/client/request.js +108 -96
- package/build/src/http-server/client/response.js +235 -213
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +29 -25
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +29 -25
- package/build/src/http-server/client/uploaded-file/uploaded-file.js +33 -33
- package/build/src/http-server/client/websocket-request.js +137 -114
- package/build/src/http-server/client/websocket-session.js +1657 -1452
- package/build/src/http-server/cookie.js +236 -216
- package/build/src/http-server/development-reloader.js +221 -190
- package/build/src/http-server/index.js +525 -451
- package/build/src/http-server/remote-address.js +50 -38
- package/build/src/http-server/server-client.js +208 -181
- package/build/src/http-server/server-lock.js +167 -153
- package/build/src/http-server/websocket-channel-subscribers.js +93 -81
- package/build/src/http-server/websocket-channel.js +117 -104
- package/build/src/http-server/websocket-connection.js +104 -96
- package/build/src/http-server/websocket-event-log-store.js +404 -350
- package/build/src/http-server/websocket-events-host.js +164 -145
- package/build/src/http-server/websocket-events.js +47 -47
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +14 -13
- package/build/src/http-server/worker-handler/in-process.js +141 -123
- package/build/src/http-server/worker-handler/index.js +349 -313
- package/build/src/http-server/worker-handler/worker-script.js +5 -4
- package/build/src/http-server/worker-handler/worker-thread.js +269 -240
- package/build/src/initializer.js +36 -31
- package/build/src/jobs/mail-delivery.js +15 -13
- package/build/src/logger/base-logger.js +26 -24
- package/build/src/logger/console-logger.js +23 -21
- package/build/src/logger/file-logger.js +31 -29
- package/build/src/logger/outputs/array-output.js +42 -37
- package/build/src/logger/outputs/console-output.js +24 -20
- package/build/src/logger/outputs/file-output.js +48 -43
- package/build/src/logger/outputs/stdout-output.js +48 -39
- package/build/src/logger.js +394 -338
- package/build/src/mailer/backends/smtp.js +163 -134
- package/build/src/mailer/base.js +251 -211
- package/build/src/mailer/delivery.js +64 -56
- package/build/src/mailer/index.js +22 -4
- package/build/src/mailer.js +13 -4
- package/build/src/plugins/sqljs-wasm-route-controller.js +52 -42
- package/build/src/plugins/sqljs-wasm-route.js +38 -28
- package/build/src/record-payload-values.js +28 -25
- package/build/src/routes/app-routes.js +14 -12
- package/build/src/routes/base-route.js +130 -112
- package/build/src/routes/basic-route.js +102 -83
- package/build/src/routes/built-in/debug/controller.js +10 -10
- package/build/src/routes/built-in/errors/controller.js +5 -5
- package/build/src/routes/get-route.js +63 -50
- package/build/src/routes/hooks/frontend-model-command-route-hook.js +80 -66
- package/build/src/routes/index.js +43 -36
- package/build/src/routes/namespace-route.js +47 -38
- package/build/src/routes/plugin-routes.js +124 -107
- package/build/src/routes/post-route.js +62 -51
- package/build/src/routes/resolver.js +494 -422
- package/build/src/routes/resource-route.js +143 -124
- package/build/src/routes/root-route.js +8 -7
- package/build/src/testing/base-expect.js +14 -13
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +405 -329
- package/build/src/testing/browser-test-app.js +29 -23
- package/build/src/testing/expect-to-change.js +50 -41
- package/build/src/testing/expect-utils.js +184 -139
- package/build/src/testing/expect.js +731 -638
- package/build/src/testing/request-client.js +85 -70
- package/build/src/testing/test-files-finder.js +339 -285
- package/build/src/testing/test-filter-parser.js +155 -124
- package/build/src/testing/test-runner.js +1020 -883
- package/build/src/testing/test-suite-splitter.js +142 -114
- package/build/src/testing/test.js +256 -216
- package/build/src/utils/backtrace-cleaner-node.js +69 -62
- package/build/src/utils/backtrace-cleaner.js +216 -188
- package/build/src/utils/ensure-error.js +7 -7
- package/build/src/utils/event-emitter.js +6 -4
- package/build/src/utils/file-exists.js +10 -9
- package/build/src/utils/format-value.js +76 -67
- package/build/src/utils/model-scope.js +31 -27
- package/build/src/utils/nest-callbacks.js +13 -10
- package/build/src/utils/plain-object.js +6 -5
- package/build/src/utils/ransack.d.ts.map +1 -1
- package/build/src/utils/ransack.js +563 -449
- package/build/src/utils/rest-args-error.js +6 -5
- package/build/src/utils/singularize-model-name.js +11 -9
- package/build/src/utils/split-sql-statements.js +79 -68
- package/build/src/utils/to-import-specifier.js +30 -24
- package/build/src/utils/with-tracked-stack-async-hooks.js +74 -60
- package/build/src/utils/with-tracked-stack.js +18 -14
- package/build/src/velocious-error.js +30 -27
- package/index.js +1 -0
- package/package.json +10 -4
- package/scripts/clean-build.js +8 -0
- package/scripts/ensure-bin-executable.js +13 -0
- package/scripts/run-tests.js +37 -0
- package/scripts/test-browser.js +486 -0
- package/src/application.js +229 -0
- package/src/authorization/ability.js +329 -0
- package/src/authorization/base-resource.js +143 -0
- package/src/background-jobs/client.js +50 -0
- package/src/background-jobs/cron-expression.js +277 -0
- package/src/background-jobs/forked-runner-child.js +86 -0
- package/src/background-jobs/job-record.js +13 -0
- package/src/background-jobs/job-registry.js +92 -0
- package/src/background-jobs/job-runner.js +107 -0
- package/src/background-jobs/job.js +77 -0
- package/src/background-jobs/json-socket.js +78 -0
- package/src/background-jobs/main.js +926 -0
- package/src/background-jobs/normalize-error.js +26 -0
- package/src/background-jobs/scheduler.js +274 -0
- package/src/background-jobs/socket-request.js +68 -0
- package/src/background-jobs/status-reporter.js +101 -0
- package/src/background-jobs/store.js +994 -0
- package/src/background-jobs/types.js +70 -0
- package/src/background-jobs/web/authorization.js +89 -0
- package/src/background-jobs/web/controller.js +280 -0
- package/src/background-jobs/web/index.js +57 -0
- package/src/background-jobs/web/path-matcher.js +74 -0
- package/src/background-jobs/web/registry.js +49 -0
- package/src/background-jobs/worker.js +683 -0
- package/src/beacon/client.js +330 -0
- package/src/beacon/in-process-broker.js +71 -0
- package/src/beacon/in-process-client.js +139 -0
- package/src/beacon/server.js +148 -0
- package/src/beacon/types.js +55 -0
- package/src/cli/base-command.js +67 -0
- package/src/cli/browser-cli.js +45 -0
- package/src/cli/commands/background-jobs-main.js +7 -0
- package/src/cli/commands/background-jobs-runner.js +7 -0
- package/src/cli/commands/background-jobs-worker.js +7 -0
- package/src/cli/commands/beacon.js +7 -0
- package/src/cli/commands/console.js +12 -0
- package/src/cli/commands/db/base-command.js +82 -0
- package/src/cli/commands/db/create.js +64 -0
- package/src/cli/commands/db/drop.js +75 -0
- package/src/cli/commands/db/migrate.js +17 -0
- package/src/cli/commands/db/reset.js +22 -0
- package/src/cli/commands/db/rollback.js +15 -0
- package/src/cli/commands/db/schema/dump.js +12 -0
- package/src/cli/commands/db/schema/load.js +12 -0
- package/src/cli/commands/db/seed.js +12 -0
- package/src/cli/commands/db/tenants/check.js +38 -0
- package/src/cli/commands/db/tenants/create.js +33 -0
- package/src/cli/commands/db/tenants/migrate.js +49 -0
- package/src/cli/commands/destroy/migration.js +7 -0
- package/src/cli/commands/generate/base-models.js +7 -0
- package/src/cli/commands/generate/frontend-models.js +12 -0
- package/src/cli/commands/generate/migration.js +7 -0
- package/src/cli/commands/generate/model.js +7 -0
- package/src/cli/commands/init.js +11 -0
- package/src/cli/commands/routes.js +7 -0
- package/src/cli/commands/run-script.js +12 -0
- package/src/cli/commands/runner.js +12 -0
- package/src/cli/commands/server.js +7 -0
- package/src/cli/commands/test.js +9 -0
- package/src/cli/index.js +152 -0
- package/src/cli/tenant-database-command-helper.js +198 -0
- package/src/cli/use-browser-cli.js +30 -0
- package/src/configuration-resolver.js +65 -0
- package/src/configuration-types.js +429 -0
- package/src/configuration.js +2590 -0
- package/src/controller.js +421 -0
- package/src/current-configuration.js +31 -0
- package/src/current.js +80 -0
- package/src/database/annotations-async-hooks.js +47 -0
- package/src/database/annotations.js +40 -0
- package/src/database/drivers/base-column.js +182 -0
- package/src/database/drivers/base-columns-index.js +81 -0
- package/src/database/drivers/base-foreign-key.js +104 -0
- package/src/database/drivers/base-table.js +156 -0
- package/src/database/drivers/base.js +1609 -0
- package/src/database/drivers/mssql/column.js +74 -0
- package/src/database/drivers/mssql/columns-index.js +6 -0
- package/src/database/drivers/mssql/connect-connection.js +16 -0
- package/src/database/drivers/mssql/foreign-key.js +12 -0
- package/src/database/drivers/mssql/index.js +590 -0
- package/src/database/drivers/mssql/options.js +79 -0
- package/src/database/drivers/mssql/query-parser.js +6 -0
- package/src/database/drivers/mssql/sql/alter-table.js +4 -0
- package/src/database/drivers/mssql/sql/create-database.js +36 -0
- package/src/database/drivers/mssql/sql/create-index.js +4 -0
- package/src/database/drivers/mssql/sql/create-table.js +4 -0
- package/src/database/drivers/mssql/sql/delete.js +19 -0
- package/src/database/drivers/mssql/sql/drop-database.js +36 -0
- package/src/database/drivers/mssql/sql/drop-table.js +4 -0
- package/src/database/drivers/mssql/sql/insert.js +4 -0
- package/src/database/drivers/mssql/sql/update.js +31 -0
- package/src/database/drivers/mssql/sql/upsert.js +23 -0
- package/src/database/drivers/mssql/structure-sql.js +120 -0
- package/src/database/drivers/mssql/table.js +145 -0
- package/src/database/drivers/mysql/column.js +112 -0
- package/src/database/drivers/mysql/columns-index.js +22 -0
- package/src/database/drivers/mysql/foreign-key.js +12 -0
- package/src/database/drivers/mysql/index.js +473 -0
- package/src/database/drivers/mysql/options.js +34 -0
- package/src/database/drivers/mysql/query-parser.js +6 -0
- package/src/database/drivers/mysql/query.js +37 -0
- package/src/database/drivers/mysql/sql/alter-table.js +6 -0
- package/src/database/drivers/mysql/sql/create-database.js +39 -0
- package/src/database/drivers/mysql/sql/create-index.js +6 -0
- package/src/database/drivers/mysql/sql/create-table.js +6 -0
- package/src/database/drivers/mysql/sql/delete.js +21 -0
- package/src/database/drivers/mysql/sql/drop-database.js +6 -0
- package/src/database/drivers/mysql/sql/drop-table.js +6 -0
- package/src/database/drivers/mysql/sql/insert.js +6 -0
- package/src/database/drivers/mysql/sql/update.js +33 -0
- package/src/database/drivers/mysql/sql/upsert.js +13 -0
- package/src/database/drivers/mysql/structure-sql.js +93 -0
- package/src/database/drivers/mysql/table.js +121 -0
- package/src/database/drivers/pgsql/column.js +90 -0
- package/src/database/drivers/pgsql/columns-index.js +6 -0
- package/src/database/drivers/pgsql/foreign-key.js +12 -0
- package/src/database/drivers/pgsql/index.js +441 -0
- package/src/database/drivers/pgsql/options.js +32 -0
- package/src/database/drivers/pgsql/query-parser.js +6 -0
- package/src/database/drivers/pgsql/sql/alter-table.js +6 -0
- package/src/database/drivers/pgsql/sql/create-database.js +38 -0
- package/src/database/drivers/pgsql/sql/create-index.js +6 -0
- package/src/database/drivers/pgsql/sql/create-table.js +6 -0
- package/src/database/drivers/pgsql/sql/delete.js +21 -0
- package/src/database/drivers/pgsql/sql/drop-database.js +6 -0
- package/src/database/drivers/pgsql/sql/drop-table.js +6 -0
- package/src/database/drivers/pgsql/sql/insert.js +6 -0
- package/src/database/drivers/pgsql/sql/update.js +33 -0
- package/src/database/drivers/pgsql/sql/upsert.js +14 -0
- package/src/database/drivers/pgsql/structure-sql.js +126 -0
- package/src/database/drivers/pgsql/table.js +135 -0
- package/src/database/drivers/sqlite/base.js +509 -0
- package/src/database/drivers/sqlite/column.js +75 -0
- package/src/database/drivers/sqlite/columns-index.js +30 -0
- package/src/database/drivers/sqlite/connection-sql-js.js +46 -0
- package/src/database/drivers/sqlite/foreign-key.js +24 -0
- package/src/database/drivers/sqlite/index.js +394 -0
- package/src/database/drivers/sqlite/index.native.js +72 -0
- package/src/database/drivers/sqlite/index.web.js +99 -0
- package/src/database/drivers/sqlite/options.js +32 -0
- package/src/database/drivers/sqlite/query-parser.js +6 -0
- package/src/database/drivers/sqlite/query.js +35 -0
- package/src/database/drivers/sqlite/query.native.js +35 -0
- package/src/database/drivers/sqlite/query.web.js +49 -0
- package/src/database/drivers/sqlite/sql/alter-table.js +187 -0
- package/src/database/drivers/sqlite/sql/create-index.js +6 -0
- package/src/database/drivers/sqlite/sql/create-table.js +6 -0
- package/src/database/drivers/sqlite/sql/delete.js +26 -0
- package/src/database/drivers/sqlite/sql/drop-table.js +6 -0
- package/src/database/drivers/sqlite/sql/insert.js +6 -0
- package/src/database/drivers/sqlite/sql/update.js +33 -0
- package/src/database/drivers/sqlite/sql/upsert.js +14 -0
- package/src/database/drivers/sqlite/structure-sql.js +56 -0
- package/src/database/drivers/sqlite/table-rebuilder.js +96 -0
- package/src/database/drivers/sqlite/table.js +131 -0
- package/src/database/drivers/structure-sql/utils.js +35 -0
- package/src/database/handler.js +13 -0
- package/src/database/initializer-from-require-context.js +101 -0
- package/src/database/migration/index.js +438 -0
- package/src/database/migrator/files-finder.js +55 -0
- package/src/database/migrator/types.js +31 -0
- package/src/database/migrator.js +557 -0
- package/src/database/pool/async-tracked-multi-connection.js +1164 -0
- package/src/database/pool/base-methods-forward.js +52 -0
- package/src/database/pool/base.js +380 -0
- package/src/database/pool/single-multi-use.js +118 -0
- package/src/database/query/alter-table-base.js +104 -0
- package/src/database/query/base.js +49 -0
- package/src/database/query/create-database-base.js +42 -0
- package/src/database/query/create-index-base.js +117 -0
- package/src/database/query/create-table-base.js +205 -0
- package/src/database/query/delete-base.js +19 -0
- package/src/database/query/drop-database-base.js +38 -0
- package/src/database/query/drop-table-base.js +58 -0
- package/src/database/query/from-base.js +36 -0
- package/src/database/query/from-plain.js +16 -0
- package/src/database/query/from-table.js +18 -0
- package/src/database/query/index.js +533 -0
- package/src/database/query/insert-base.js +172 -0
- package/src/database/query/join-base.js +43 -0
- package/src/database/query/join-object.js +167 -0
- package/src/database/query/join-plain.js +18 -0
- package/src/database/query/join-tracker.js +93 -0
- package/src/database/query/model-class-query.js +1577 -0
- package/src/database/query/order-base.js +33 -0
- package/src/database/query/order-column.js +77 -0
- package/src/database/query/order-plain.js +28 -0
- package/src/database/query/preloader/belongs-to.js +267 -0
- package/src/database/query/preloader/ensure-model-class-initialized.js +18 -0
- package/src/database/query/preloader/has-many.js +316 -0
- package/src/database/query/preloader/has-one.js +123 -0
- package/src/database/query/preloader/selection.js +152 -0
- package/src/database/query/preloader.js +201 -0
- package/src/database/query/query-data.js +305 -0
- package/src/database/query/select-base.js +30 -0
- package/src/database/query/select-plain.js +18 -0
- package/src/database/query/select-table-and-column.js +28 -0
- package/src/database/query/update-base.js +41 -0
- package/src/database/query/upsert-base.js +103 -0
- package/src/database/query/where-base.js +38 -0
- package/src/database/query/where-combinator.js +31 -0
- package/src/database/query/where-hash.js +77 -0
- package/src/database/query/where-model-class-hash.js +505 -0
- package/src/database/query/where-not.js +23 -0
- package/src/database/query/where-plain.js +20 -0
- package/src/database/query/with-count.js +219 -0
- package/src/database/query-parser/base-query-parser.js +40 -0
- package/src/database/query-parser/from-parser.js +49 -0
- package/src/database/query-parser/group-parser.js +55 -0
- package/src/database/query-parser/joins-parser.js +37 -0
- package/src/database/query-parser/limit-parser.js +77 -0
- package/src/database/query-parser/options.js +94 -0
- package/src/database/query-parser/order-parser.js +45 -0
- package/src/database/query-parser/select-parser.js +67 -0
- package/src/database/query-parser/where-parser.js +46 -0
- package/src/database/record/acts-as-list.js +374 -0
- package/src/database/record/attachments/download.js +49 -0
- package/src/database/record/attachments/handle.js +188 -0
- package/src/database/record/attachments/normalize-input.js +213 -0
- package/src/database/record/attachments/storage-drivers/filesystem.js +114 -0
- package/src/database/record/attachments/storage-drivers/native.js +146 -0
- package/src/database/record/attachments/storage-drivers/s3.js +245 -0
- package/src/database/record/attachments/store.js +591 -0
- package/src/database/record/index.js +3970 -0
- package/src/database/record/instance-relationships/base.js +289 -0
- package/src/database/record/instance-relationships/belongs-to.js +84 -0
- package/src/database/record/instance-relationships/has-many.js +284 -0
- package/src/database/record/instance-relationships/has-one.js +117 -0
- package/src/database/record/record-not-found-error.js +3 -0
- package/src/database/record/relationships/base.js +195 -0
- package/src/database/record/relationships/belongs-to.js +57 -0
- package/src/database/record/relationships/has-many.js +46 -0
- package/src/database/record/relationships/has-one.js +46 -0
- package/src/database/record/state-machine.js +278 -0
- package/src/database/record/user-module.js +43 -0
- package/src/database/record/validators/base.js +27 -0
- package/src/database/record/validators/format.js +50 -0
- package/src/database/record/validators/presence.js +24 -0
- package/src/database/record/validators/uniqueness.js +124 -0
- package/src/database/table-data/index.js +241 -0
- package/src/database/table-data/table-column.js +416 -0
- package/src/database/table-data/table-foreign-key.js +69 -0
- package/src/database/table-data/table-index.js +46 -0
- package/src/database/table-data/table-reference.js +13 -0
- package/src/database/use-database.js +48 -0
- package/src/environment-handlers/base.js +561 -0
- package/src/environment-handlers/browser.js +338 -0
- package/src/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
- package/src/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
- package/src/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
- package/src/environment-handlers/node/cli/commands/beacon.js +21 -0
- package/src/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
- package/src/environment-handlers/node/cli/commands/console.js +149 -0
- package/src/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
- package/src/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
- package/src/environment-handlers/node/cli/commands/db/seed.js +79 -0
- package/src/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
- package/src/environment-handlers/node/cli/commands/generate/base-models.js +367 -0
- package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
- package/src/environment-handlers/node/cli/commands/generate/migration.js +45 -0
- package/src/environment-handlers/node/cli/commands/generate/model.js +45 -0
- package/src/environment-handlers/node/cli/commands/init.js +68 -0
- package/src/environment-handlers/node/cli/commands/routes.js +63 -0
- package/src/environment-handlers/node/cli/commands/run-script.js +85 -0
- package/src/environment-handlers/node/cli/commands/runner.js +84 -0
- package/src/environment-handlers/node/cli/commands/server.js +151 -0
- package/src/environment-handlers/node/cli/commands/test.js +118 -0
- package/src/environment-handlers/node.js +887 -0
- package/src/error-logger.js +30 -0
- package/src/frontend-model-controller.js +3491 -0
- package/src/frontend-model-resource/base-resource.js +935 -0
- package/src/frontend-models/base.js +4004 -0
- package/src/frontend-models/clear-pending-debounced-callback.js +16 -0
- package/src/frontend-models/event-hook-models.js +49 -0
- package/src/frontend-models/model-registry.js +28 -0
- package/src/frontend-models/outgoing-event-buffer.js +51 -0
- package/src/frontend-models/preloader.js +169 -0
- package/src/frontend-models/query.js +2245 -0
- package/src/frontend-models/resource-config-validation.js +56 -0
- package/src/frontend-models/resource-definition.js +399 -0
- package/src/frontend-models/transport-serialization.js +369 -0
- package/src/frontend-models/use-created-event.js +21 -0
- package/src/frontend-models/use-destroyed-event.js +148 -0
- package/src/frontend-models/use-model-class-event.js +164 -0
- package/src/frontend-models/use-updated-event.js +152 -0
- package/src/frontend-models/websocket-channel.js +494 -0
- package/src/frontend-models/websocket-publishers.js +224 -0
- package/src/http-client/header.js +17 -0
- package/src/http-client/index.js +139 -0
- package/src/http-client/request.js +94 -0
- package/src/http-client/response.js +151 -0
- package/src/http-client/websocket-client.js +27 -0
- package/src/http-server/client/index.js +507 -0
- package/src/http-server/client/params-to-object.js +152 -0
- package/src/http-server/client/request-buffer/form-data-part.js +139 -0
- package/src/http-server/client/request-buffer/header.js +19 -0
- package/src/http-server/client/request-buffer/index.js +535 -0
- package/src/http-server/client/request-parser.js +195 -0
- package/src/http-server/client/request-runner.js +321 -0
- package/src/http-server/client/request-timing.js +171 -0
- package/src/http-server/client/request.js +114 -0
- package/src/http-server/client/response.js +251 -0
- package/src/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
- package/src/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
- package/src/http-server/client/uploaded-file/uploaded-file.js +36 -0
- package/src/http-server/client/websocket-request.js +147 -0
- package/src/http-server/client/websocket-session.js +1755 -0
- package/src/http-server/cookie.js +245 -0
- package/src/http-server/development-reloader.js +240 -0
- package/src/http-server/index.js +561 -0
- package/src/http-server/remote-address.js +77 -0
- package/src/http-server/server-client.js +222 -0
- package/src/http-server/server-lock.js +178 -0
- package/src/http-server/websocket-channel-subscribers.js +110 -0
- package/src/http-server/websocket-channel.js +137 -0
- package/src/http-server/websocket-connection.js +118 -0
- package/src/http-server/websocket-event-log-store.js +433 -0
- package/src/http-server/websocket-events-host.js +170 -0
- package/src/http-server/websocket-events.js +50 -0
- package/src/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
- package/src/http-server/worker-handler/in-process.js +155 -0
- package/src/http-server/worker-handler/index.js +370 -0
- package/src/http-server/worker-handler/worker-script.js +6 -0
- package/src/http-server/worker-handler/worker-thread.js +286 -0
- package/src/initializer.js +39 -0
- package/src/jobs/.gitkeep +1 -0
- package/src/jobs/mail-delivery.js +22 -0
- package/src/logger/base-logger.js +34 -0
- package/src/logger/console-logger.js +28 -0
- package/src/logger/file-logger.js +36 -0
- package/src/logger/outputs/array-output.js +50 -0
- package/src/logger/outputs/console-output.js +32 -0
- package/src/logger/outputs/file-output.js +55 -0
- package/src/logger/outputs/stdout-output.js +64 -0
- package/src/logger.js +507 -0
- package/src/mailer/backends/smtp.js +197 -0
- package/src/mailer/base.js +337 -0
- package/src/mailer/delivery.js +70 -0
- package/src/mailer/index.js +24 -0
- package/src/mailer.js +15 -0
- package/src/plugins/sqljs-wasm-route-controller.js +70 -0
- package/src/plugins/sqljs-wasm-route.js +71 -0
- package/src/record-payload-values.js +83 -0
- package/src/routes/app-routes.js +17 -0
- package/src/routes/base-route.js +133 -0
- package/src/routes/basic-route.js +109 -0
- package/src/routes/built-in/debug/controller.js +12 -0
- package/src/routes/built-in/errors/controller.js +7 -0
- package/src/routes/built-in/errors/not-found.ejs +1 -0
- package/src/routes/get-route.js +75 -0
- package/src/routes/hooks/frontend-model-command-route-hook.js +100 -0
- package/src/routes/index.js +50 -0
- package/src/routes/namespace-route.js +51 -0
- package/src/routes/plugin-routes.js +141 -0
- package/src/routes/post-route.js +74 -0
- package/src/routes/resolver.js +535 -0
- package/src/routes/resource-route.js +154 -0
- package/src/routes/root-route.js +11 -0
- package/src/templates/configuration.js +61 -0
- package/src/templates/generate-migration.js +11 -0
- package/src/templates/generate-model.js +6 -0
- package/src/templates/routes.js +11 -0
- package/src/testing/base-expect.js +17 -0
- package/src/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
- package/src/testing/browser-test-app.js +32 -0
- package/src/testing/expect-to-change.js +55 -0
- package/src/testing/expect-utils.js +269 -0
- package/src/testing/expect.js +763 -0
- package/src/testing/request-client.js +90 -0
- package/src/testing/test-files-finder.js +364 -0
- package/src/testing/test-filter-parser.js +198 -0
- package/src/testing/test-runner.js +1168 -0
- package/src/testing/test-suite-splitter.js +177 -0
- package/src/testing/test.js +370 -0
- package/src/types/external-modules.d.ts +57 -0
- package/src/utils/backtrace-cleaner-node.js +87 -0
- package/src/utils/backtrace-cleaner.js +266 -0
- package/src/utils/ensure-error.js +15 -0
- package/src/utils/event-emitter.js +8 -0
- package/src/utils/file-exists.js +18 -0
- package/src/utils/format-value.js +101 -0
- package/src/utils/model-scope.js +56 -0
- package/src/utils/nest-callbacks.js +22 -0
- package/src/utils/plain-object.js +14 -0
- package/src/utils/ransack.js +859 -0
- package/src/utils/rest-args-error.js +14 -0
- package/src/utils/singularize-model-name.js +18 -0
- package/src/utils/split-sql-statements.js +88 -0
- package/src/utils/to-import-specifier.js +53 -0
- package/src/utils/with-tracked-stack-async-hooks.js +103 -0
- package/src/utils/with-tracked-stack.js +38 -0
- package/src/velocious-error.js +34 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {resolveFrontendModelClass} from "./model-registry.js"
|
|
4
|
+
import isPlainObject from "../utils/plain-object.js"
|
|
5
|
+
|
|
6
|
+
const TYPE_KEY = "__velocious_type"
|
|
7
|
+
const TYPE_DATE = "date"
|
|
8
|
+
const TYPE_UNDEFINED = "undefined"
|
|
9
|
+
const TYPE_BIGINT = "bigint"
|
|
10
|
+
const TYPE_NUMBER = "number"
|
|
11
|
+
const TYPE_FRONTEND_MODEL = "frontend_model"
|
|
12
|
+
const NUMBER_NAN = "NaN"
|
|
13
|
+
const NUMBER_POSITIVE_INFINITY = "Infinity"
|
|
14
|
+
const NUMBER_NEGATIVE_INFINITY = "-Infinity"
|
|
15
|
+
const PRELOADED_RELATIONSHIPS_KEY = "__preloadedRelationships"
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Assign a key to a plain object without triggering the `__proto__` setter.
|
|
19
|
+
* Uses `Object.defineProperty` so that keys like `__proto__` are stored as
|
|
20
|
+
* own data properties instead of mutating the object's prototype chain. This
|
|
21
|
+
* lets callers receive a regular `{}` object (with `Object.prototype` and a
|
|
22
|
+
* normal `constructor.name`) while still preventing prototype pollution.
|
|
23
|
+
* @param {Record<string, ?>} target - Target object.
|
|
24
|
+
* @param {string} key - Property key.
|
|
25
|
+
* @param {?} value - Property value.
|
|
26
|
+
* @returns {void}
|
|
27
|
+
*/
|
|
28
|
+
export function assignSafeProperty(target, key, value) {
|
|
29
|
+
Object.defineProperty(target, key, {
|
|
30
|
+
value,
|
|
31
|
+
writable: true,
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Runs is undefined marker.
|
|
39
|
+
* @param {?} value - Candidate value.
|
|
40
|
+
* @returns {boolean} - Whether value is encoded undefined marker.
|
|
41
|
+
*/
|
|
42
|
+
function isUndefinedMarker(value) {
|
|
43
|
+
if (!isPlainObject(value)) return false
|
|
44
|
+
|
|
45
|
+
const keys = Object.keys(value)
|
|
46
|
+
|
|
47
|
+
return keys.length === 1 && Object.prototype.hasOwnProperty.call(value, TYPE_KEY) && value[TYPE_KEY] === TYPE_UNDEFINED
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a value is a typed marker object with a string `value` field.
|
|
52
|
+
* @param {?} value - Candidate marker.
|
|
53
|
+
* @param {string} markerType - Expected marker type value.
|
|
54
|
+
* @param {(stringValue: string) => boolean} valueMatches - Additional string value predicate.
|
|
55
|
+
* @returns {boolean} - Whether value matches the marker shape.
|
|
56
|
+
*/
|
|
57
|
+
function isStringValueMarker(value, markerType, valueMatches) {
|
|
58
|
+
if (!isPlainObject(value)) return false
|
|
59
|
+
|
|
60
|
+
const keys = Object.keys(value)
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
keys.length === 2
|
|
64
|
+
&& Object.prototype.hasOwnProperty.call(value, TYPE_KEY)
|
|
65
|
+
&& Object.prototype.hasOwnProperty.call(value, "value")
|
|
66
|
+
&& value[TYPE_KEY] === markerType
|
|
67
|
+
&& typeof value.value === "string"
|
|
68
|
+
&& valueMatches(value.value)
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Runs is date marker.
|
|
74
|
+
* @param {?} value - Candidate value.
|
|
75
|
+
* @returns {boolean} - Whether value is encoded date marker.
|
|
76
|
+
*/
|
|
77
|
+
function isDateMarker(value) {
|
|
78
|
+
return isStringValueMarker(value, TYPE_DATE, () => true)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Runs is big int marker.
|
|
83
|
+
* @param {?} value - Candidate value.
|
|
84
|
+
* @returns {boolean} - Whether value is encoded bigint marker.
|
|
85
|
+
*/
|
|
86
|
+
function isBigIntMarker(value) {
|
|
87
|
+
return isStringValueMarker(value, TYPE_BIGINT, (stringValue) => /^-?\d+$/.test(stringValue))
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Runs is non finite number marker.
|
|
92
|
+
* @param {?} value - Candidate value.
|
|
93
|
+
* @returns {boolean} - Whether value is encoded non-finite number marker.
|
|
94
|
+
*/
|
|
95
|
+
function isNonFiniteNumberMarker(value) {
|
|
96
|
+
if (!isPlainObject(value)) return false
|
|
97
|
+
|
|
98
|
+
const keys = Object.keys(value)
|
|
99
|
+
const markerValue = value.value
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
keys.length === 2
|
|
103
|
+
&& Object.prototype.hasOwnProperty.call(value, TYPE_KEY)
|
|
104
|
+
&& Object.prototype.hasOwnProperty.call(value, "value")
|
|
105
|
+
&& value[TYPE_KEY] === TYPE_NUMBER
|
|
106
|
+
&& (markerValue === NUMBER_NAN || markerValue === NUMBER_POSITIVE_INFINITY || markerValue === NUMBER_NEGATIVE_INFINITY)
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Runs is frontend model marker.
|
|
112
|
+
* @param {?} value - Candidate value.
|
|
113
|
+
* @returns {value is {__velocious_type: "frontend_model", attributes: Record<string, ?>, modelName: string, preloadedRelationships?: Record<string, ?>}} - Whether value is encoded frontend-model marker.
|
|
114
|
+
*/
|
|
115
|
+
function isFrontendModelMarker(value) {
|
|
116
|
+
if (!isPlainObject(value)) return false
|
|
117
|
+
|
|
118
|
+
const modelName = value.modelName
|
|
119
|
+
const attributes = value.attributes
|
|
120
|
+
const preloadedRelationships = value.preloadedRelationships
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
Object.prototype.hasOwnProperty.call(value, TYPE_KEY)
|
|
124
|
+
&& value[TYPE_KEY] === TYPE_FRONTEND_MODEL
|
|
125
|
+
&& typeof modelName === "string"
|
|
126
|
+
&& modelName.length > 0
|
|
127
|
+
&& isPlainObject(attributes)
|
|
128
|
+
&& (preloadedRelationships === undefined || isPlainObject(preloadedRelationships))
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Runs the isBackendModelInstance helper.
|
|
134
|
+
* @param {?} value - Candidate value.
|
|
135
|
+
* @returns {value is {attributes: () => Record<string, ?>, constructor: {getModelName?: () => string, name?: string}, getModelClass: () => {getRelationshipsMap: () => Record<string, ?>}, getRelationshipByName: (relationshipName: string) => {getPreloaded: () => boolean, loaded: () => ?}}} - Whether value looks like a backend model instance.
|
|
136
|
+
*/
|
|
137
|
+
export function isBackendModelInstance(value) {
|
|
138
|
+
if (!value || typeof value !== "object") return false
|
|
139
|
+
|
|
140
|
+
const candidate = /**
|
|
141
|
+
* Narrows the runtime value to the documented type.
|
|
142
|
+
@type {Record<string, ?>} */ (value)
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
typeof candidate.attributes === "function"
|
|
146
|
+
&& typeof candidate.getModelClass === "function"
|
|
147
|
+
&& typeof candidate.getRelationshipByName === "function"
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Runs serialize frontend model transport value internal.
|
|
153
|
+
* @param {?} value - Value to serialize.
|
|
154
|
+
* @param {WeakSet<object>} seenModels - Models already visited in the current recursion path.
|
|
155
|
+
* @returns {?} - Serialized value with transport markers.
|
|
156
|
+
*/
|
|
157
|
+
function serializeFrontendModelTransportValueInternal(value, seenModels) {
|
|
158
|
+
if (value === undefined) {
|
|
159
|
+
return {[TYPE_KEY]: TYPE_UNDEFINED}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (value instanceof Date) {
|
|
163
|
+
return {
|
|
164
|
+
[TYPE_KEY]: TYPE_DATE,
|
|
165
|
+
value: value.toISOString()
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (typeof value === "bigint") {
|
|
170
|
+
return {
|
|
171
|
+
[TYPE_KEY]: TYPE_BIGINT,
|
|
172
|
+
value: value.toString()
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
177
|
+
const markerValue = Number.isNaN(value)
|
|
178
|
+
? NUMBER_NAN
|
|
179
|
+
: (value > 0 ? NUMBER_POSITIVE_INFINITY : NUMBER_NEGATIVE_INFINITY)
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
[TYPE_KEY]: TYPE_NUMBER,
|
|
183
|
+
value: markerValue
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (Array.isArray(value)) {
|
|
188
|
+
return value.map((entry) => serializeFrontendModelTransportValueInternal(entry, seenModels))
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (isBackendModelInstance(value)) {
|
|
192
|
+
const modelAttributes = value.attributes()
|
|
193
|
+
const modelClass = value.constructor
|
|
194
|
+
const modelName = typeof modelClass.getModelName === "function" ? modelClass.getModelName() : modelClass.name
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Serialized model.
|
|
198
|
+
@type {Record<string, ?>} */
|
|
199
|
+
const serializedModel = {
|
|
200
|
+
[TYPE_KEY]: TYPE_FRONTEND_MODEL,
|
|
201
|
+
attributes: /**
|
|
202
|
+
* Narrows the runtime value to the documented type.
|
|
203
|
+
@type {Record<string, ?>} */ (serializeFrontendModelTransportValueInternal(modelAttributes, seenModels)),
|
|
204
|
+
modelName
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (seenModels.has(value)) {
|
|
208
|
+
return serializedModel
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
seenModels.add(value)
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Preloaded relationships.
|
|
215
|
+
@type {Record<string, ?>} */
|
|
216
|
+
const preloadedRelationships = {}
|
|
217
|
+
const relationshipsMap = value.getModelClass().getRelationshipsMap()
|
|
218
|
+
|
|
219
|
+
for (const relationshipName of Object.keys(relationshipsMap)) {
|
|
220
|
+
const relationship = value.getRelationshipByName(relationshipName)
|
|
221
|
+
|
|
222
|
+
if (!relationship.getPreloaded()) continue
|
|
223
|
+
|
|
224
|
+
const loadedRelationship = relationship.loaded()
|
|
225
|
+
|
|
226
|
+
assignSafeProperty(preloadedRelationships, relationshipName, serializeFrontendModelTransportValueInternal(
|
|
227
|
+
loadedRelationship == undefined ? null : loadedRelationship,
|
|
228
|
+
seenModels
|
|
229
|
+
))
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
seenModels.delete(value)
|
|
233
|
+
|
|
234
|
+
if (Object.keys(preloadedRelationships).length > 0) {
|
|
235
|
+
serializedModel.preloadedRelationships = preloadedRelationships
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return serializedModel
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (isPlainObject(value)) {
|
|
242
|
+
/**
|
|
243
|
+
* Serialized.
|
|
244
|
+
@type {Record<string, ?>} */
|
|
245
|
+
const serialized = {}
|
|
246
|
+
|
|
247
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
248
|
+
assignSafeProperty(serialized, key, serializeFrontendModelTransportValueInternal(nestedValue, seenModels))
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return serialized
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return value
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Runs deserialize frontend model marker.
|
|
259
|
+
* @param {{attributes: Record<string, ?>, modelName: string, preloadedRelationships?: Record<string, ?>}} marker - Encoded frontend-model marker.
|
|
260
|
+
* @returns {?} - Hydrated frontend model or plain object fallback.
|
|
261
|
+
*/
|
|
262
|
+
function deserializeFrontendModelMarker(marker) {
|
|
263
|
+
const attributes = /**
|
|
264
|
+
* Narrows the runtime value to the documented type.
|
|
265
|
+
@type {Record<string, ?>} */ (deserializeFrontendModelTransportValue(marker.attributes))
|
|
266
|
+
const preloadedRelationships = isPlainObject(marker.preloadedRelationships)
|
|
267
|
+
? /**
|
|
268
|
+
* Narrows the runtime value to the documented type.
|
|
269
|
+
@type {Record<string, ?>} */ (deserializeFrontendModelTransportValue(marker.preloadedRelationships))
|
|
270
|
+
: {}
|
|
271
|
+
const modelClass = resolveFrontendModelClass(marker.modelName)
|
|
272
|
+
|
|
273
|
+
if (!modelClass || typeof modelClass.instantiateFromResponse !== "function") {
|
|
274
|
+
if (Object.keys(preloadedRelationships).length < 1) {
|
|
275
|
+
return attributes
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
...attributes,
|
|
280
|
+
[PRELOADED_RELATIONSHIPS_KEY]: preloadedRelationships
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Route hydration through `instantiateFromResponse` so
|
|
285
|
+
// `__abilities` / `__queryData` / `__associationCounts` /
|
|
286
|
+
// `__preloadedRelationships` baked into the marker's attributes blob (e.g.
|
|
287
|
+
// by `resource.serialize` in custom-command auto-serialization) get
|
|
288
|
+
// extracted and applied. Legacy markers that used a separate top-level
|
|
289
|
+
// `preloadedRelationships` field merge them under the standard key first
|
|
290
|
+
// so `modelDataFromResponse` picks them up.
|
|
291
|
+
const responseAttributes = Object.keys(preloadedRelationships).length > 0
|
|
292
|
+
? {
|
|
293
|
+
...attributes,
|
|
294
|
+
[PRELOADED_RELATIONSHIPS_KEY]: preloadedRelationships
|
|
295
|
+
}
|
|
296
|
+
: attributes
|
|
297
|
+
|
|
298
|
+
return modelClass.instantiateFromResponse(responseAttributes)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Runs the serializeFrontendModelTransportValue helper.
|
|
303
|
+
* @param {?} value - Value to serialize.
|
|
304
|
+
* @returns {?} - Serialized value with transport markers.
|
|
305
|
+
*/
|
|
306
|
+
export function serializeFrontendModelTransportValue(value) {
|
|
307
|
+
return serializeFrontendModelTransportValueInternal(value, new WeakSet())
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Runs the deserializeFrontendModelTransportValue helper.
|
|
312
|
+
* @param {?} value - Value to deserialize.
|
|
313
|
+
* @returns {?} - Deserialized value with transport markers restored.
|
|
314
|
+
*/
|
|
315
|
+
export function deserializeFrontendModelTransportValue(value) {
|
|
316
|
+
if (isUndefinedMarker(value)) {
|
|
317
|
+
return undefined
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (isDateMarker(value)) {
|
|
321
|
+
const dateValue = /**
|
|
322
|
+
* Narrows the runtime value to the documented type.
|
|
323
|
+
@type {{value: string}} */ (value).value
|
|
324
|
+
|
|
325
|
+
return new Date(dateValue)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (isBigIntMarker(value)) {
|
|
329
|
+
const bigintValue = /**
|
|
330
|
+
* Narrows the runtime value to the documented type.
|
|
331
|
+
@type {{value: string}} */ (value).value
|
|
332
|
+
|
|
333
|
+
return BigInt(bigintValue)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (isNonFiniteNumberMarker(value)) {
|
|
337
|
+
const numberValue = /**
|
|
338
|
+
* Narrows the runtime value to the documented type.
|
|
339
|
+
@type {{value: string}} */ (value).value
|
|
340
|
+
|
|
341
|
+
if (numberValue === NUMBER_NAN) return Number.NaN
|
|
342
|
+
if (numberValue === NUMBER_POSITIVE_INFINITY) return Number.POSITIVE_INFINITY
|
|
343
|
+
|
|
344
|
+
return Number.NEGATIVE_INFINITY
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (isFrontendModelMarker(value)) {
|
|
348
|
+
return deserializeFrontendModelMarker(value)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (Array.isArray(value)) {
|
|
352
|
+
return value.map((entry) => deserializeFrontendModelTransportValue(entry))
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (isPlainObject(value)) {
|
|
356
|
+
/**
|
|
357
|
+
* Deserialized.
|
|
358
|
+
@type {Record<string, ?>} */
|
|
359
|
+
const deserialized = {}
|
|
360
|
+
|
|
361
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
362
|
+
assignSafeProperty(deserialized, key, deserializeFrontendModelTransportValue(nestedValue))
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return deserialized
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return value
|
|
369
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import useModelClassEvent from "./use-model-class-event.js"
|
|
4
|
+
|
|
5
|
+
/** @typedef {typeof import("./base.js").default} FrontendModelClass */
|
|
6
|
+
/** @typedef {import("./use-model-class-event.js").FrontendModelCreateUpdateEventPayload} FrontendModelCreateEventPayload */
|
|
7
|
+
/** @typedef {import("./use-model-class-event.js").UseModelClassEventOptions} UseCreatedEventOptions */
|
|
8
|
+
/** @typedef {(payload: FrontendModelCreateEventPayload) => void} FrontendModelCreateEventCallback */
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* React hook for frontend-model class create events.
|
|
12
|
+
* @param {FrontendModelClass | null | undefined} modelClass - Frontend model class.
|
|
13
|
+
* @param {FrontendModelCreateEventCallback} callback - Event callback.
|
|
14
|
+
* @param {UseCreatedEventOptions} [options] - Hook options.
|
|
15
|
+
* @returns {void}
|
|
16
|
+
*/
|
|
17
|
+
export default function useCreatedEvent(modelClass, callback, options = {}) {
|
|
18
|
+
useModelClassEvent(modelClass, "create", (payload) => {
|
|
19
|
+
callback(/** @type {FrontendModelCreateEventPayload} */ (payload))
|
|
20
|
+
}, options)
|
|
21
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import debounceFunction from "debounce"
|
|
4
|
+
import {useEffect, useMemo, useRef} from "react"
|
|
5
|
+
|
|
6
|
+
import clearPendingDebouncedCallback from "./clear-pending-debounced-callback.js"
|
|
7
|
+
import {modelsDependencyKey, modelsFromInput} from "./event-hook-models.js"
|
|
8
|
+
import useModelClassEvent from "./use-model-class-event.js"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* FrontendModelClass type.
|
|
12
|
+
@typedef {typeof import("./base.js").default} FrontendModelClass */
|
|
13
|
+
/**
|
|
14
|
+
* FrontendModelInstance type.
|
|
15
|
+
@typedef {import("./base.js").default} FrontendModelInstance */
|
|
16
|
+
/**
|
|
17
|
+
* FrontendModelClassDestroyEventPayload type.
|
|
18
|
+
@typedef {import("./use-model-class-event.js").FrontendModelDestroyEventPayload} FrontendModelClassDestroyEventPayload */
|
|
19
|
+
/**
|
|
20
|
+
* Defines this typedef.
|
|
21
|
+
@typedef {{id: string}} FrontendModelInstanceDestroyEventPayload */
|
|
22
|
+
/**
|
|
23
|
+
* FrontendModelDestroyEventPayload type.
|
|
24
|
+
@typedef {FrontendModelClassDestroyEventPayload | FrontendModelInstanceDestroyEventPayload} FrontendModelDestroyEventPayload */
|
|
25
|
+
/**
|
|
26
|
+
* UseDestroyedEventOptions type.
|
|
27
|
+
@typedef {import("./use-model-class-event.js").UseModelClassEventOptions} UseDestroyedEventOptions */
|
|
28
|
+
/**
|
|
29
|
+
* FrontendModelDestroyEventCallback type.
|
|
30
|
+
@typedef {(payload: FrontendModelDestroyEventPayload) => void} FrontendModelDestroyEventCallback */
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Runs assert no unknown options.
|
|
34
|
+
* @param {Record<string, import("./query.js").FrontendModelTransportValue | (() => void) | undefined>} restOptions - Unknown options object.
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
function assertNoUnknownOptions(restOptions) {
|
|
38
|
+
const unknownOptionNames = Object.keys(restOptions)
|
|
39
|
+
|
|
40
|
+
if (unknownOptionNames.length === 0) return
|
|
41
|
+
|
|
42
|
+
throw new Error(`Unknown options given to useDestroyedEvent: ${unknownOptionNames.join(", ")}`)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Runs event query dependency payload.
|
|
47
|
+
* @param {import("./query.js").default<FrontendModelClass> | undefined} query - Event query option.
|
|
48
|
+
* @returns {import("./query.js").FrontendModelEventOptionsPayload | null} Stable dependency payload.
|
|
49
|
+
*/
|
|
50
|
+
function eventQueryDependencyPayload(query) {
|
|
51
|
+
if (!query) return null
|
|
52
|
+
|
|
53
|
+
return query.eventOptionsPayload()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* React hook for frontend-model destroy events. Pass a model class for class-level
|
|
58
|
+
* destroy events, or a model / model array for instance-level destroy events.
|
|
59
|
+
* @param {FrontendModelClass | FrontendModelInstance | FrontendModelInstance[] | null | undefined} modelClassOrModels - Model class, model, or models.
|
|
60
|
+
* @param {FrontendModelDestroyEventCallback} callback - Event callback.
|
|
61
|
+
* @param {UseDestroyedEventOptions} [options] - Hook options.
|
|
62
|
+
* @returns {void}
|
|
63
|
+
*/
|
|
64
|
+
export default function useDestroyedEvent(modelClassOrModels, callback, options = {}) {
|
|
65
|
+
const {active = true, abilities, debounce = false, onConnected, preload, query, queryData, select, selectsExtra, withCount, ...restOptions} = options
|
|
66
|
+
assertNoUnknownOptions(restOptions)
|
|
67
|
+
|
|
68
|
+
const classModel = typeof modelClassOrModels === "function" ? modelClassOrModels : null
|
|
69
|
+
const instanceModels = typeof modelClassOrModels === "function" ? null : modelClassOrModels
|
|
70
|
+
const projectionOptions = {abilities, preload, query, queryData, select, selectsExtra, withCount}
|
|
71
|
+
|
|
72
|
+
useModelClassEvent(classModel, "destroy", callback, {active: active && Boolean(classModel), debounce, onConnected, ...projectionOptions})
|
|
73
|
+
useInstanceDestroyedEvent(instanceModels, callback, {active: active && !classModel, debounce, onConnected, ...projectionOptions})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Runs use instance destroyed event.
|
|
78
|
+
* @param {FrontendModelInstance | FrontendModelInstance[] | null | undefined} modelOrModels - Model or models.
|
|
79
|
+
* @param {FrontendModelDestroyEventCallback} callback - Event callback.
|
|
80
|
+
* @param {UseDestroyedEventOptions} options - Hook options.
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
function useInstanceDestroyedEvent(modelOrModels, callback, options) {
|
|
84
|
+
const {active = true, abilities, debounce = false, onConnected, preload, query, queryData, select, selectsExtra, withCount} = options
|
|
85
|
+
const projectionKey = JSON.stringify({abilities, preload, query: eventQueryDependencyPayload(query), queryData, select, selectsExtra, withCount})
|
|
86
|
+
const projectionOptionsRef = useRef({abilities, preload, query, queryData, select, selectsExtra, withCount})
|
|
87
|
+
const callbackRef = useRef(callback)
|
|
88
|
+
const activeRef = useRef(active)
|
|
89
|
+
projectionOptionsRef.current = {abilities, preload, query, queryData, select, selectsExtra, withCount}
|
|
90
|
+
callbackRef.current = callback
|
|
91
|
+
activeRef.current = active
|
|
92
|
+
|
|
93
|
+
const modelsKey = modelsDependencyKey(modelOrModels)
|
|
94
|
+
const eventCallback = useMemo(() => {
|
|
95
|
+
const wrappedCallback = (/**
|
|
96
|
+
* Narrows the runtime value to the documented type.
|
|
97
|
+
@type {FrontendModelInstanceDestroyEventPayload} */ payload) => {
|
|
98
|
+
if (activeRef.current) callbackRef.current(payload)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (typeof debounce === "number") return debounceFunction(wrappedCallback, debounce)
|
|
102
|
+
if (debounce) return debounceFunction(wrappedCallback)
|
|
103
|
+
|
|
104
|
+
return wrappedCallback
|
|
105
|
+
}, [debounce])
|
|
106
|
+
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (!active) return undefined
|
|
109
|
+
|
|
110
|
+
const models = modelsFromInput(modelOrModels)
|
|
111
|
+
if (models.length < 1) return undefined
|
|
112
|
+
|
|
113
|
+
let closed = false
|
|
114
|
+
/**
|
|
115
|
+
* Unsubscribe callbacks.
|
|
116
|
+
@type {Array<() => void>} */
|
|
117
|
+
const unsubscribeCallbacks = []
|
|
118
|
+
const subscriptionCallback = (/**
|
|
119
|
+
* Narrows the runtime value to the documented type.
|
|
120
|
+
@type {FrontendModelInstanceDestroyEventPayload} */ payload) => {
|
|
121
|
+
if (!closed) eventCallback(payload)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
void (async () => {
|
|
125
|
+
for (const model of models) {
|
|
126
|
+
const unsubscribe = await model.onDestroy(subscriptionCallback, projectionOptionsRef.current)
|
|
127
|
+
|
|
128
|
+
if (closed) {
|
|
129
|
+
unsubscribe()
|
|
130
|
+
} else {
|
|
131
|
+
unsubscribeCallbacks.push(unsubscribe)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!closed && onConnected) onConnected()
|
|
136
|
+
})()
|
|
137
|
+
|
|
138
|
+
return () => {
|
|
139
|
+
closed = true
|
|
140
|
+
|
|
141
|
+
for (const unsubscribe of unsubscribeCallbacks) {
|
|
142
|
+
unsubscribe()
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
clearPendingDebouncedCallback(eventCallback)
|
|
146
|
+
}
|
|
147
|
+
}, [active, eventCallback, modelsKey, onConnected, projectionKey])
|
|
148
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import debounceFunction from "debounce"
|
|
4
|
+
import {useEffect, useMemo, useRef} from "react"
|
|
5
|
+
|
|
6
|
+
import clearPendingDebouncedCallback from "./clear-pending-debounced-callback.js"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* FrontendModelClass type.
|
|
10
|
+
@typedef {typeof import("./base.js").default} FrontendModelClass */
|
|
11
|
+
/**
|
|
12
|
+
* FrontendModelInstance type.
|
|
13
|
+
@typedef {InstanceType<FrontendModelClass>} FrontendModelInstance */
|
|
14
|
+
/**
|
|
15
|
+
* FrontendModelClassEventName type.
|
|
16
|
+
@typedef {"create" | "update" | "destroy"} FrontendModelClassEventName */
|
|
17
|
+
/**
|
|
18
|
+
* Defines this typedef.
|
|
19
|
+
@typedef {{id: string, model: FrontendModelInstance}} FrontendModelCreateUpdateEventPayload */
|
|
20
|
+
/**
|
|
21
|
+
* Defines this typedef.
|
|
22
|
+
@typedef {{id: string}} FrontendModelDestroyEventPayload */
|
|
23
|
+
/**
|
|
24
|
+
* FrontendModelClassEventPayload type.
|
|
25
|
+
@typedef {FrontendModelCreateUpdateEventPayload | FrontendModelDestroyEventPayload} FrontendModelClassEventPayload */
|
|
26
|
+
/**
|
|
27
|
+
* FrontendModelClassEventCallback type.
|
|
28
|
+
@typedef {(payload: FrontendModelClassEventPayload) => void} FrontendModelClassEventCallback */
|
|
29
|
+
/**
|
|
30
|
+
* Defines this typedef.
|
|
31
|
+
@typedef {{active?: boolean, debounce?: boolean | number, onConnected?: () => void} & import("./query.js").FrontendModelEventOptionsObject} UseModelClassEventOptions */
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Runs assert no unknown options.
|
|
35
|
+
* @param {Record<string, import("./query.js").FrontendModelTransportValue | (() => void) | undefined>} restOptions - Unknown options object.
|
|
36
|
+
* @returns {void}
|
|
37
|
+
*/
|
|
38
|
+
function assertNoUnknownOptions(restOptions) {
|
|
39
|
+
const unknownOptionNames = Object.keys(restOptions)
|
|
40
|
+
|
|
41
|
+
if (unknownOptionNames.length > 0) {
|
|
42
|
+
throw new Error(`Unknown options given to useModelClassEvent: ${unknownOptionNames.join(", ")}`)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Runs event query dependency payload.
|
|
48
|
+
* @param {import("./query.js").default<FrontendModelClass> | undefined} query - Event query option.
|
|
49
|
+
* @returns {import("./query.js").FrontendModelEventOptionsPayload | null} Stable dependency payload.
|
|
50
|
+
*/
|
|
51
|
+
function eventQueryDependencyPayload(query) {
|
|
52
|
+
if (!query) return null
|
|
53
|
+
|
|
54
|
+
return query.eventOptionsPayload()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Runs normalize event names.
|
|
59
|
+
* @param {FrontendModelClassEventName | FrontendModelClassEventName[]} eventOrEvents - Event name or names.
|
|
60
|
+
* @returns {FrontendModelClassEventName[]} - Normalized event names.
|
|
61
|
+
*/
|
|
62
|
+
function normalizeEventNames(eventOrEvents) {
|
|
63
|
+
return Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Runs event names dependency key.
|
|
68
|
+
* @param {FrontendModelClassEventName[]} eventNames - Event names.
|
|
69
|
+
* @returns {string} - Stable dependency key.
|
|
70
|
+
*/
|
|
71
|
+
function eventNamesDependencyKey(eventNames) {
|
|
72
|
+
return eventNames.join("|")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Runs subscribe to model class event.
|
|
77
|
+
* @param {FrontendModelClass} modelClass - Frontend model class.
|
|
78
|
+
* @param {FrontendModelClassEventName} eventName - Event name.
|
|
79
|
+
* @param {FrontendModelClassEventCallback} callback - Event callback.
|
|
80
|
+
* @param {import("./query.js").FrontendModelEventOptionsObject} options - Event query or record projection options.
|
|
81
|
+
* @returns {Promise<() => void>} - Unsubscribe callback.
|
|
82
|
+
*/
|
|
83
|
+
async function subscribeToModelClassEvent(modelClass, eventName, callback, options) {
|
|
84
|
+
if (eventName === "create") return await modelClass.onCreate(callback, options)
|
|
85
|
+
if (eventName === "update") return await modelClass.onUpdate(callback, options)
|
|
86
|
+
if (eventName === "destroy") return await modelClass.onDestroy(callback, options)
|
|
87
|
+
|
|
88
|
+
throw new Error(`Unsupported frontend model class event: ${eventName}`)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* React hook for frontend-model class lifecycle events.
|
|
93
|
+
* @param {FrontendModelClass | null | undefined} modelClass - Frontend model class.
|
|
94
|
+
* @param {FrontendModelClassEventName | FrontendModelClassEventName[]} eventOrEvents - Event name or names.
|
|
95
|
+
* @param {FrontendModelClassEventCallback} callback - Event callback.
|
|
96
|
+
* @param {UseModelClassEventOptions} [options] - Hook options.
|
|
97
|
+
* @returns {void}
|
|
98
|
+
*/
|
|
99
|
+
export default function useModelClassEvent(modelClass, eventOrEvents, callback, options = {}) {
|
|
100
|
+
const {active = true, abilities, debounce = false, onConnected, preload, query, queryData, select, selectsExtra, withCount, ...restOptions} = options
|
|
101
|
+
assertNoUnknownOptions(restOptions)
|
|
102
|
+
|
|
103
|
+
const projectionKey = JSON.stringify({abilities, preload, query: eventQueryDependencyPayload(query), queryData, select, selectsExtra, withCount})
|
|
104
|
+
const projectionOptionsRef = useRef({abilities, preload, query, queryData, select, selectsExtra, withCount})
|
|
105
|
+
const callbackRef = useRef(callback)
|
|
106
|
+
const activeRef = useRef(active)
|
|
107
|
+
projectionOptionsRef.current = {abilities, preload, query, queryData, select, selectsExtra, withCount}
|
|
108
|
+
callbackRef.current = callback
|
|
109
|
+
activeRef.current = active
|
|
110
|
+
|
|
111
|
+
const eventNames = normalizeEventNames(eventOrEvents)
|
|
112
|
+
const eventsKey = eventNamesDependencyKey(eventNames)
|
|
113
|
+
const eventCallback = useMemo(() => {
|
|
114
|
+
const wrappedCallback = (/**
|
|
115
|
+
* Narrows the runtime value to the documented type.
|
|
116
|
+
@type {FrontendModelClassEventPayload} */ payload) => {
|
|
117
|
+
if (activeRef.current) callbackRef.current(payload)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (typeof debounce === "number") return debounceFunction(wrappedCallback, debounce)
|
|
121
|
+
if (debounce) return debounceFunction(wrappedCallback)
|
|
122
|
+
|
|
123
|
+
return wrappedCallback
|
|
124
|
+
}, [debounce])
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (!active || !modelClass) return undefined
|
|
128
|
+
|
|
129
|
+
let closed = false
|
|
130
|
+
/**
|
|
131
|
+
* Unsubscribe callbacks.
|
|
132
|
+
@type {Array<() => void>} */
|
|
133
|
+
const unsubscribeCallbacks = []
|
|
134
|
+
const subscriptionCallback = (/**
|
|
135
|
+
* Narrows the runtime value to the documented type.
|
|
136
|
+
@type {FrontendModelClassEventPayload} */ payload) => {
|
|
137
|
+
if (!closed) eventCallback(payload)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void (async () => {
|
|
141
|
+
for (const eventName of eventNames) {
|
|
142
|
+
const unsubscribe = await subscribeToModelClassEvent(modelClass, eventName, subscriptionCallback, projectionOptionsRef.current)
|
|
143
|
+
|
|
144
|
+
if (closed) {
|
|
145
|
+
unsubscribe()
|
|
146
|
+
} else {
|
|
147
|
+
unsubscribeCallbacks.push(unsubscribe)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!closed && onConnected) onConnected()
|
|
152
|
+
})()
|
|
153
|
+
|
|
154
|
+
return () => {
|
|
155
|
+
closed = true
|
|
156
|
+
|
|
157
|
+
for (const unsubscribe of unsubscribeCallbacks) {
|
|
158
|
+
unsubscribe()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
clearPendingDebouncedCallback(eventCallback)
|
|
162
|
+
}
|
|
163
|
+
}, [active, eventsKey, eventCallback, modelClass, onConnected, projectionKey])
|
|
164
|
+
}
|