velocious 1.0.563 → 1.0.564

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +2 -0
  2. package/build/background-jobs/cron-expression.js +12 -13
  3. package/build/background-jobs/main.js +6 -6
  4. package/build/background-jobs/runner-graceful-shutdown.js +2 -3
  5. package/build/background-jobs/scheduler.js +3 -3
  6. package/build/background-jobs/worker.js +8 -9
  7. package/build/beacon/client.js +3 -4
  8. package/build/database/drivers/sqlite/web-persistence.js +2 -5
  9. package/build/database/pool/async-tracked-multi-connection.js +65 -15
  10. package/build/database/pool/base.js +23 -7
  11. package/build/database/query/index.js +21 -22
  12. package/build/database/query/model-class-query.js +5 -6
  13. package/build/database/record/attachments/normalize-input.js +9 -10
  14. package/build/database/record/attachments/store.js +2 -2
  15. package/build/database/record/auditing.js +7 -8
  16. package/build/database/record/index.js +4 -5
  17. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +1 -2
  18. package/build/frontend-model-controller.js +49 -56
  19. package/build/frontend-models/base.js +17 -19
  20. package/build/frontend-models/outgoing-event-buffer.js +3 -4
  21. package/build/frontend-models/query.js +40 -44
  22. package/build/frontend-models/resource-definition.js +7 -8
  23. package/build/frontend-models/transport-serialization.js +10 -12
  24. package/build/frontend-models/websocket-channel.js +12 -13
  25. package/build/http-server/client/websocket-session.js +4 -5
  26. package/build/http-server/client-delivery-queue.js +7 -8
  27. package/build/http-server/websocket-event-log-store.js +4 -6
  28. package/build/plugins/sqljs-wasm-route.js +3 -5
  29. package/build/src/background-jobs/cron-expression.d.ts +0 -12
  30. package/build/src/background-jobs/cron-expression.d.ts.map +1 -1
  31. package/build/src/background-jobs/cron-expression.js +13 -13
  32. package/build/src/background-jobs/main.d.ts.map +1 -1
  33. package/build/src/background-jobs/main.js +7 -7
  34. package/build/src/background-jobs/runner-graceful-shutdown.d.ts +0 -6
  35. package/build/src/background-jobs/runner-graceful-shutdown.d.ts.map +1 -1
  36. package/build/src/background-jobs/runner-graceful-shutdown.js +3 -3
  37. package/build/src/background-jobs/scheduler.d.ts +0 -3
  38. package/build/src/background-jobs/scheduler.d.ts.map +1 -1
  39. package/build/src/background-jobs/scheduler.js +4 -4
  40. package/build/src/background-jobs/worker.d.ts +0 -8
  41. package/build/src/background-jobs/worker.d.ts.map +1 -1
  42. package/build/src/background-jobs/worker.js +9 -9
  43. package/build/src/beacon/client.d.ts +0 -4
  44. package/build/src/beacon/client.d.ts.map +1 -1
  45. package/build/src/beacon/client.js +4 -4
  46. package/build/src/database/drivers/sqlite/web-persistence.d.ts +0 -14
  47. package/build/src/database/drivers/sqlite/web-persistence.d.ts.map +1 -1
  48. package/build/src/database/drivers/sqlite/web-persistence.js +3 -3
  49. package/build/src/database/pool/async-tracked-multi-connection.d.ts +29 -1
  50. package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
  51. package/build/src/database/pool/async-tracked-multi-connection.js +57 -15
  52. package/build/src/database/pool/base.d.ts +53 -4
  53. package/build/src/database/pool/base.d.ts.map +1 -1
  54. package/build/src/database/pool/base.js +23 -6
  55. package/build/src/database/query/index.d.ts +18 -39
  56. package/build/src/database/query/index.d.ts.map +1 -1
  57. package/build/src/database/query/index.js +22 -22
  58. package/build/src/database/query/model-class-query.d.ts +0 -5
  59. package/build/src/database/query/model-class-query.d.ts.map +1 -1
  60. package/build/src/database/query/model-class-query.js +6 -6
  61. package/build/src/database/record/attachments/normalize-input.d.ts +0 -9
  62. package/build/src/database/record/attachments/normalize-input.d.ts.map +1 -1
  63. package/build/src/database/record/attachments/normalize-input.js +10 -10
  64. package/build/src/database/record/attachments/store.d.ts.map +1 -1
  65. package/build/src/database/record/attachments/store.js +2 -2
  66. package/build/src/database/record/auditing.d.ts +17 -24
  67. package/build/src/database/record/auditing.d.ts.map +1 -1
  68. package/build/src/database/record/auditing.js +8 -8
  69. package/build/src/database/record/index.d.ts +4 -4
  70. package/build/src/database/record/index.d.ts.map +1 -1
  71. package/build/src/database/record/index.js +5 -5
  72. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +0 -39
  73. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  74. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +2 -2
  75. package/build/src/frontend-model-controller.d.ts +1 -1
  76. package/build/src/frontend-model-controller.d.ts.map +1 -1
  77. package/build/src/frontend-model-controller.js +50 -50
  78. package/build/src/frontend-models/base.d.ts.map +1 -1
  79. package/build/src/frontend-models/base.js +18 -18
  80. package/build/src/frontend-models/outgoing-event-buffer.d.ts.map +1 -1
  81. package/build/src/frontend-models/outgoing-event-buffer.js +3 -3
  82. package/build/src/frontend-models/query.d.ts +56 -37
  83. package/build/src/frontend-models/query.d.ts.map +1 -1
  84. package/build/src/frontend-models/query.js +39 -39
  85. package/build/src/frontend-models/resource-definition.d.ts +0 -7
  86. package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
  87. package/build/src/frontend-models/resource-definition.js +8 -8
  88. package/build/src/frontend-models/transport-serialization.d.ts +0 -10
  89. package/build/src/frontend-models/transport-serialization.d.ts.map +1 -1
  90. package/build/src/frontend-models/transport-serialization.js +11 -11
  91. package/build/src/frontend-models/websocket-channel.d.ts +0 -12
  92. package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
  93. package/build/src/frontend-models/websocket-channel.js +13 -13
  94. package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
  95. package/build/src/http-server/client/websocket-session.js +5 -5
  96. package/build/src/http-server/client-delivery-queue.d.ts +7 -7
  97. package/build/src/http-server/client-delivery-queue.d.ts.map +1 -1
  98. package/build/src/http-server/client-delivery-queue.js +8 -8
  99. package/build/src/http-server/websocket-event-log-store.d.ts +0 -14
  100. package/build/src/http-server/websocket-event-log-store.d.ts.map +1 -1
  101. package/build/src/http-server/websocket-event-log-store.js +5 -5
  102. package/build/src/plugins/sqljs-wasm-route.d.ts.map +1 -1
  103. package/build/src/plugins/sqljs-wasm-route.js +4 -4
  104. package/build/src/sync/conflict-strategy.d.ts +0 -15
  105. package/build/src/sync/conflict-strategy.d.ts.map +1 -1
  106. package/build/src/sync/conflict-strategy.js +3 -3
  107. package/build/src/sync/device-identity.d.ts +0 -45
  108. package/build/src/sync/device-identity.d.ts.map +1 -1
  109. package/build/src/sync/device-identity.js +4 -4
  110. package/build/src/sync/local-mutation-log.d.ts +0 -41
  111. package/build/src/sync/local-mutation-log.d.ts.map +1 -1
  112. package/build/src/sync/local-mutation-log.js +9 -9
  113. package/build/src/sync/offline-grant.d.ts +0 -26
  114. package/build/src/sync/offline-grant.d.ts.map +1 -1
  115. package/build/src/sync/offline-grant.js +4 -4
  116. package/build/src/sync/peer-mutation-bundle.d.ts +0 -14
  117. package/build/src/sync/peer-mutation-bundle.d.ts.map +1 -1
  118. package/build/src/sync/peer-mutation-bundle.js +3 -3
  119. package/build/src/sync/server-change-feed.d.ts.map +1 -1
  120. package/build/src/sync/server-change-feed.js +33 -33
  121. package/build/src/sync/sync-api-client.d.ts +0 -9
  122. package/build/src/sync/sync-api-client.d.ts.map +1 -1
  123. package/build/src/sync/sync-api-client.js +2 -2
  124. package/build/src/sync/sync-envelope-replay-service.d.ts +38 -21
  125. package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
  126. package/build/src/sync/sync-envelope-replay-service.js +18 -18
  127. package/build/src/sync/sync-resource-base.d.ts +0 -7
  128. package/build/src/sync/sync-resource-base.d.ts.map +1 -1
  129. package/build/src/sync/sync-resource-base.js +2 -2
  130. package/build/src/sync/sync-scope-store.d.ts +0 -9
  131. package/build/src/sync/sync-scope-store.d.ts.map +1 -1
  132. package/build/src/sync/sync-scope-store.js +10 -10
  133. package/build/src/testing/test-filter-parser.d.ts +0 -10
  134. package/build/src/testing/test-filter-parser.d.ts.map +1 -1
  135. package/build/src/testing/test-filter-parser.js +11 -11
  136. package/build/src/testing/test-runner.d.ts +25 -91
  137. package/build/src/testing/test-runner.d.ts.map +1 -1
  138. package/build/src/testing/test-runner.js +113 -98
  139. package/build/src/testing/test.d.ts +8 -0
  140. package/build/src/testing/test.d.ts.map +1 -1
  141. package/build/src/testing/test.js +9 -9
  142. package/build/src/utils/backtrace-cleaner.d.ts.map +1 -1
  143. package/build/src/utils/backtrace-cleaner.js +9 -9
  144. package/build/src/utils/model-scope.d.ts +0 -8
  145. package/build/src/utils/model-scope.d.ts.map +1 -1
  146. package/build/src/utils/model-scope.js +3 -3
  147. package/build/src/utils/ransack.d.ts +52 -19
  148. package/build/src/utils/ransack.d.ts.map +1 -1
  149. package/build/src/utils/ransack.js +26 -26
  150. package/build/sync/conflict-strategy.js +3 -6
  151. package/build/sync/device-identity.js +4 -9
  152. package/build/sync/local-mutation-log.js +9 -14
  153. package/build/sync/offline-grant.js +4 -7
  154. package/build/sync/peer-mutation-bundle.js +2 -4
  155. package/build/sync/server-change-feed.js +32 -34
  156. package/build/sync/sync-api-client.js +1 -2
  157. package/build/sync/sync-envelope-replay-service.js +17 -19
  158. package/build/sync/sync-resource-base.js +1 -2
  159. package/build/sync/sync-scope-store.js +9 -10
  160. package/build/testing/test-filter-parser.js +10 -11
  161. package/build/testing/test-runner.js +116 -108
  162. package/build/testing/test.js +8 -9
  163. package/build/utils/backtrace-cleaner.js +8 -9
  164. package/build/utils/model-scope.js +3 -4
  165. package/build/utils/ransack.js +27 -34
  166. package/package.json +2 -1
  167. package/scripts/eslint-rules/typedefs-first.js +67 -0
  168. package/scripts/prewarm-chromedriver.js +26 -0
  169. package/src/background-jobs/cron-expression.js +12 -13
  170. package/src/background-jobs/main.js +6 -6
  171. package/src/background-jobs/runner-graceful-shutdown.js +2 -3
  172. package/src/background-jobs/scheduler.js +3 -3
  173. package/src/background-jobs/worker.js +8 -9
  174. package/src/beacon/client.js +3 -4
  175. package/src/database/drivers/sqlite/web-persistence.js +2 -5
  176. package/src/database/pool/async-tracked-multi-connection.js +65 -15
  177. package/src/database/pool/base.js +23 -7
  178. package/src/database/query/index.js +21 -22
  179. package/src/database/query/model-class-query.js +5 -6
  180. package/src/database/record/attachments/normalize-input.js +9 -10
  181. package/src/database/record/attachments/store.js +2 -2
  182. package/src/database/record/auditing.js +7 -8
  183. package/src/database/record/index.js +4 -5
  184. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +1 -2
  185. package/src/frontend-model-controller.js +49 -56
  186. package/src/frontend-models/base.js +17 -19
  187. package/src/frontend-models/outgoing-event-buffer.js +3 -4
  188. package/src/frontend-models/query.js +40 -44
  189. package/src/frontend-models/resource-definition.js +7 -8
  190. package/src/frontend-models/transport-serialization.js +10 -12
  191. package/src/frontend-models/websocket-channel.js +12 -13
  192. package/src/http-server/client/websocket-session.js +4 -5
  193. package/src/http-server/client-delivery-queue.js +7 -8
  194. package/src/http-server/websocket-event-log-store.js +4 -6
  195. package/src/plugins/sqljs-wasm-route.js +3 -5
  196. package/src/sync/conflict-strategy.js +3 -6
  197. package/src/sync/device-identity.js +4 -9
  198. package/src/sync/local-mutation-log.js +9 -14
  199. package/src/sync/offline-grant.js +4 -7
  200. package/src/sync/peer-mutation-bundle.js +2 -4
  201. package/src/sync/server-change-feed.js +32 -34
  202. package/src/sync/sync-api-client.js +1 -2
  203. package/src/sync/sync-envelope-replay-service.js +17 -19
  204. package/src/sync/sync-resource-base.js +1 -2
  205. package/src/sync/sync-scope-store.js +9 -10
  206. package/src/testing/test-filter-parser.js +10 -11
  207. package/src/testing/test-runner.js +116 -108
  208. package/src/testing/test.js +8 -9
  209. package/src/utils/backtrace-cleaner.js +8 -9
  210. package/src/utils/model-scope.js +3 -4
  211. package/src/utils/ransack.js +27 -34
@@ -57,6 +57,10 @@ import ValidatorsUniqueness from "./validators/uniqueness.js"
57
57
  import registerActsAsListCallbacks from "./acts-as-list.js"
58
58
  import UUID from "pure-uuid"
59
59
 
60
+ /**
61
+ * Translation record shape used by translated attributes.
62
+ * @typedef {VelociousDatabaseRecord & {locale: function(): string}} TranslationBase
63
+ */
60
64
  /**
61
65
  * AttachmentDriverConstructor type.
62
66
  * @typedef {import("../../configuration-types.js").AttachmentDriverConstructor} AttachmentDriverConstructor
@@ -4452,11 +4456,6 @@ class VelociousDatabaseRecord {
4452
4456
  }
4453
4457
  }
4454
4458
 
4455
- /**
4456
- * Translation record shape used by translated attributes.
4457
- * @typedef {VelociousDatabaseRecord & {locale: function(): string}} TranslationBase
4458
- */
4459
-
4460
4459
  VelociousDatabaseRecord.registerValidatorType("format", ValidatorsFormat)
4461
4460
  VelociousDatabaseRecord.registerValidatorType("length", ValidatorsLength)
4462
4461
  VelociousDatabaseRecord.registerValidatorType("presence", ValidatorsPresence)
@@ -6,8 +6,6 @@ import * as inflection from "inflection"
6
6
  import {frontendModelResourceIsBuiltIn, frontendModelResourcesWithBuiltInsForBackendProject} from "../../../../../frontend-models/built-in-resources.js"
7
7
  import {frontendModelResourceClassFromDefinition, frontendModelResourceConfigurationFromDefinition} from "../../../../../frontend-models/resource-definition.js"
8
8
 
9
- const FRONTEND_MODELS_REGENERATE_COMMAND = "velocious generate:frontend-models"
10
-
11
9
  /**
12
10
  * Attribute metadata used for generated frontend-model JSDoc.
13
11
  * @typedef {object} FrontendAttributeConfig
@@ -47,6 +45,7 @@ const FRONTEND_MODELS_REGENERATE_COMMAND = "velocious generate:frontend-models"
47
45
  * @property {string | null} sourceFile - Source file that declared the method.
48
46
  * @property {string} type - JSDoc parameter type.
49
47
  */
48
+ const FRONTEND_MODELS_REGENERATE_COMMAND = "velocious generate:frontend-models"
50
49
 
51
50
  /** Node CLI command that generates frontend model classes from backend project resource config. */
52
51
  export default class DbGenerateFrontendModels extends BaseCommand {
@@ -20,6 +20,55 @@ import isDate from "./utils/is-date.js"
20
20
  import isPlainObject from "./utils/plain-object.js"
21
21
  import {RansackQueryError, normalizeRansackGroup, parseRansackSort} from "./utils/ransack.js"
22
22
 
23
+ /**
24
+ * FrontendModelSearch type.
25
+ * @typedef {object} FrontendModelSearch
26
+ * @property {string[]} path - Relationship path.
27
+ * @property {string} column - Column or attribute name.
28
+ * @property {"eq" | "like" | "notEq" | "gt" | "gteq" | "lt" | "lteq"} operator - Search operator.
29
+ * @property {?} value - Search value.
30
+ */
31
+ /**
32
+ * FrontendModelSort type.
33
+ * @typedef {object} FrontendModelSort
34
+ * @property {string} column - Attribute name to sort by.
35
+ * @property {"asc" | "desc"} direction - Sort direction.
36
+ * @property {string[]} path - Relationship path from root model.
37
+ */
38
+ /**
39
+ * FrontendModelGroup type.
40
+ * @typedef {object} FrontendModelGroup
41
+ * @property {string} column - Attribute name to group by.
42
+ * @property {string[]} path - Relationship path from root model.
43
+ */
44
+ /**
45
+ * FrontendModelPluck type.
46
+ * @typedef {object} FrontendModelPluck
47
+ * @property {string} column - Attribute name to pluck.
48
+ * @property {string[]} path - Relationship path from root model.
49
+ */
50
+ /**
51
+ * FrontendModelPagination type.
52
+ * @typedef {object} FrontendModelPagination
53
+ * @property {number | null} limit - Maximum number of records.
54
+ * @property {number | null} offset - Number of records to skip.
55
+ * @property {number | null} page - 1-based page number.
56
+ * @property {number | null} perPage - Page size.
57
+ */
58
+ /**
59
+ * @typedef {import("./configuration-types.js").ClientErrorPayloadContext & {
60
+ * action: string,
61
+ * expectedError: boolean,
62
+ * frontendModelEndpoint: true
63
+ * }} FrontendModelEndpointErrorContext
64
+ */
65
+ /**
66
+ * FrontendModelIndexQueryOptions type.
67
+ * @typedef {object} FrontendModelIndexQueryOptions
68
+ * @property {boolean} [includePagination] - Whether frontend-model pagination params should be applied.
69
+ * @property {boolean} [includeSort] - Whether frontend-model sort params should be applied.
70
+ * @property {import("./frontend-model-resource/base-resource.js").default} [resource] - Resource providing query hooks.
71
+ */
23
72
  /** @typedef {import("./database/query/model-class-query.js").default & Record<symbol, Set<string> | undefined>} FrontendModelQueryMetadata */
24
73
 
25
74
  /**
@@ -114,62 +163,6 @@ function normalizeFrontendModelSelect(select, rootModelName = null) {
114
163
  return normalized
115
164
  }
116
165
 
117
- /**
118
- * FrontendModelSearch type.
119
- * @typedef {object} FrontendModelSearch
120
- * @property {string[]} path - Relationship path.
121
- * @property {string} column - Column or attribute name.
122
- * @property {"eq" | "like" | "notEq" | "gt" | "gteq" | "lt" | "lteq"} operator - Search operator.
123
- * @property {?} value - Search value.
124
- */
125
-
126
- /**
127
- * FrontendModelSort type.
128
- * @typedef {object} FrontendModelSort
129
- * @property {string} column - Attribute name to sort by.
130
- * @property {"asc" | "desc"} direction - Sort direction.
131
- * @property {string[]} path - Relationship path from root model.
132
- */
133
-
134
- /**
135
- * FrontendModelGroup type.
136
- * @typedef {object} FrontendModelGroup
137
- * @property {string} column - Attribute name to group by.
138
- * @property {string[]} path - Relationship path from root model.
139
- */
140
-
141
- /**
142
- * FrontendModelPluck type.
143
- * @typedef {object} FrontendModelPluck
144
- * @property {string} column - Attribute name to pluck.
145
- * @property {string[]} path - Relationship path from root model.
146
- */
147
-
148
- /**
149
- * FrontendModelPagination type.
150
- * @typedef {object} FrontendModelPagination
151
- * @property {number | null} limit - Maximum number of records.
152
- * @property {number | null} offset - Number of records to skip.
153
- * @property {number | null} page - 1-based page number.
154
- * @property {number | null} perPage - Page size.
155
- */
156
-
157
- /**
158
- * @typedef {import("./configuration-types.js").ClientErrorPayloadContext & {
159
- * action: string,
160
- * expectedError: boolean,
161
- * frontendModelEndpoint: true
162
- * }} FrontendModelEndpointErrorContext
163
- */
164
-
165
- /**
166
- * FrontendModelIndexQueryOptions type.
167
- * @typedef {object} FrontendModelIndexQueryOptions
168
- * @property {boolean} [includePagination] - Whether frontend-model pagination params should be applied.
169
- * @property {boolean} [includeSort] - Whether frontend-model sort params should be applied.
170
- * @property {import("./frontend-model-resource/base-resource.js").default} [resource] - Resource providing query hooks.
171
- */
172
-
173
166
  const frontendModelJoinedPathsSymbol = Symbol("frontendModelJoinedPaths")
174
167
  const frontendModelGroupedColumnsSymbol = Symbol("frontendModelGroupedColumns")
175
168
  const frontendModelWhereNoMatchSymbol = Symbol("frontendModelWhereNoMatch")
@@ -17,6 +17,23 @@ import {defineModelScope} from "../utils/model-scope.js"
17
17
  import isPlainObject from "../utils/plain-object.js"
18
18
  import {readPayloadAssociationCount, readPayloadComputedAbility, readPayloadQueryData, setPayloadAssociationCount, setPayloadComputedAbility, setPayloadQueryData} from "../record-payload-values.js"
19
19
 
20
+ /**
21
+ * Frontend model relationship helper type. Returned by `getRelationshipByName`,
22
+ * which generated models immediately cast to their concrete relationship type
23
+ * (e.g. `FrontendModelSingularRelationship<Owner, Target, TargetCreateAttributes>`).
24
+ * The members use `any` type args so that cast is allowed regardless of the
25
+ * target model's typed-attribute generics — a concrete `FrontendModelBase` member
26
+ * here makes the cast a non-overlapping (TS2352) error for every typed model.
27
+ * @typedef {FrontendModelHasManyRelationship<any, any, any> | FrontendModelSingularRelationship<any, any, any>} FrontendModelRelationship
28
+ */
29
+ /**
30
+ * Defines this typedef.
31
+ * @typedef {{callback: (payload: {id: string, model: FrontendModelBase}) => void, eventFilterKey: string | null, eventFilterPayload: import("./query.js").FrontendModelEventFilterPayload | null, projectionPayload: import("./query.js").FrontendModelProjectionPayload}} FrontendModelModelEventCallbackEntry
32
+ */
33
+ /**
34
+ * Defines this typedef.
35
+ * @typedef {{callback: (payload: {id: string}) => void}} FrontendModelDestroyEventCallbackEntry
36
+ */
20
37
  /**
21
38
  * FrontendModelCommandType type.
22
39
  * @typedef {"create" | "find" | "index" | "update" | "destroy" | "attach" | "attachmentList" | "download" | "url"} FrontendModelCommandType */
@@ -658,16 +675,6 @@ export class FrontendModelHasManyRelationship {
658
675
  }
659
676
  }
660
677
 
661
- /**
662
- * Frontend model relationship helper type. Returned by `getRelationshipByName`,
663
- * which generated models immediately cast to their concrete relationship type
664
- * (e.g. `FrontendModelSingularRelationship<Owner, Target, TargetCreateAttributes>`).
665
- * The members use `any` type args so that cast is allowed regardless of the
666
- * target model's typed-attribute generics — a concrete `FrontendModelBase` member
667
- * here makes the cast a non-overlapping (TS2352) error for every typed model.
668
- * @typedef {FrontendModelHasManyRelationship<any, any, any> | FrontendModelSingularRelationship<any, any, any>} FrontendModelRelationship
669
- */
670
-
671
678
  /**
672
679
  * Copies loaded relationship state between helpers of the same relationship shape.
673
680
  * @param {object} args - Arguments.
@@ -1279,15 +1286,6 @@ function cloneFrontendModelAttributes(value) {
1279
1286
  */
1280
1287
  const FRONTEND_MODELS_CHANNEL_NAME = "frontend-models"
1281
1288
 
1282
- /**
1283
- * Defines this typedef.
1284
- * @typedef {{callback: (payload: {id: string, model: FrontendModelBase}) => void, eventFilterKey: string | null, eventFilterPayload: import("./query.js").FrontendModelEventFilterPayload | null, projectionPayload: import("./query.js").FrontendModelProjectionPayload}} FrontendModelModelEventCallbackEntry
1285
- */
1286
- /**
1287
- * Defines this typedef.
1288
- * @typedef {{callback: (payload: {id: string}) => void}} FrontendModelDestroyEventCallbackEntry
1289
- */
1290
-
1291
1289
  /**
1292
1290
  * Runs merge frontend model event preload.
1293
1291
  * @param {Record<string, import("./query.js").FrontendModelTransportValue>} target - Target preload payload.
@@ -1,13 +1,12 @@
1
- // @ts-check
2
-
3
- const MAX_BUFFERED_OUTGOING_EVENTS = 50
4
-
5
1
  /**
6
2
  * BufferedOutgoingEvent type.
7
3
  * @typedef {object} BufferedOutgoingEvent
8
4
  * @property {string} customPath - Request path.
9
5
  * @property {Record<string, ?>} payload - Command payload.
10
6
  */
7
+ // @ts-check
8
+
9
+ const MAX_BUFFERED_OUTGOING_EVENTS = 50
11
10
 
12
11
  /**
13
12
  * Buffer.
@@ -5,28 +5,6 @@ import {normalizeRansackGroup, parseRansackSort} from "../utils/ransack.js"
5
5
  import {isModelScopeDescriptor} from "../utils/model-scope.js"
6
6
  import isPlainObject from "../utils/plain-object.js"
7
7
 
8
- /** Error raised when a frontend-model query descriptor is malformed. */
9
- export class FrontendModelQueryError extends Error {
10
- /**
11
- * Creates a frontend-model query error.
12
- * @param {string} message - Error message.
13
- */
14
- constructor(message) {
15
- super(message)
16
-
17
- this.name = "FrontendModelQueryError"
18
- }
19
- }
20
-
21
- /**
22
- * Builds a query descriptor error.
23
- * @param {string} message - Error message.
24
- * @returns {FrontendModelQueryError} - Query descriptor error.
25
- */
26
- function frontendModelQueryError(message) {
27
- return new FrontendModelQueryError(message)
28
- }
29
-
30
8
  /**
31
9
  * FrontendModelSearch type.
32
10
  * @typedef {object} FrontendModelSearch
@@ -97,6 +75,46 @@ function frontendModelQueryError(message) {
97
75
  * @property {FrontendModelEventFilterPayload | null} eventFilterPayload - Normalized event filter payload, or null when unfiltered.
98
76
  * @property {FrontendModelProjectionPayload} projectionPayload - Normalized event serialization projection payload.
99
77
  */
78
+ /**
79
+ * FrontendModelSort type.
80
+ * @typedef {object} FrontendModelSort
81
+ * @property {string} column - Attribute name to sort by.
82
+ * @property {"asc" | "desc"} direction - Sort direction.
83
+ * @property {string[]} path - Relationship path from root model.
84
+ */
85
+ /**
86
+ * FrontendModelGroup type.
87
+ * @typedef {object} FrontendModelGroup
88
+ * @property {string} column - Attribute name to group by.
89
+ * @property {string[]} path - Relationship path from root model.
90
+ */
91
+ /**
92
+ * FrontendModelPluck type.
93
+ * @typedef {object} FrontendModelPluck
94
+ * @property {string} column - Attribute name to pluck.
95
+ * @property {string[]} path - Relationship path from root model.
96
+ */
97
+ /** Error raised when a frontend-model query descriptor is malformed. */
98
+ export class FrontendModelQueryError extends Error {
99
+ /**
100
+ * Creates a frontend-model query error.
101
+ * @param {string} message - Error message.
102
+ */
103
+ constructor(message) {
104
+ super(message)
105
+
106
+ this.name = "FrontendModelQueryError"
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Builds a query descriptor error.
112
+ * @param {string} message - Error message.
113
+ * @returns {FrontendModelQueryError} - Query descriptor error.
114
+ */
115
+ function frontendModelQueryError(message) {
116
+ return new FrontendModelQueryError(message)
117
+ }
100
118
 
101
119
  /**
102
120
  * Runs the normalizePreload helper.
@@ -490,28 +508,6 @@ export function normalizeJoins(joins) {
490
508
  return normalized
491
509
  }
492
510
 
493
- /**
494
- * FrontendModelSort type.
495
- * @typedef {object} FrontendModelSort
496
- * @property {string} column - Attribute name to sort by.
497
- * @property {"asc" | "desc"} direction - Sort direction.
498
- * @property {string[]} path - Relationship path from root model.
499
- */
500
-
501
- /**
502
- * FrontendModelGroup type.
503
- * @typedef {object} FrontendModelGroup
504
- * @property {string} column - Attribute name to group by.
505
- * @property {string[]} path - Relationship path from root model.
506
- */
507
-
508
- /**
509
- * FrontendModelPluck type.
510
- * @typedef {object} FrontendModelPluck
511
- * @property {string} column - Attribute name to pluck.
512
- * @property {string[]} path - Relationship path from root model.
513
- */
514
-
515
511
  /**
516
512
  * Runs normalize sort direction.
517
513
  * @param {?} direction - Direction value.
@@ -5,6 +5,13 @@ import FrontendModelBaseResource from "../frontend-model-resource/base-resource.
5
5
  import restArgsError from "../utils/rest-args-error.js"
6
6
  import {validateFrontendModelResourceCommandName} from "./resource-config-validation.js"
7
7
 
8
+ /**
9
+ * Resolved frontend-model resource registration for a replay resource type.
10
+ * @typedef {object} FrontendModelResolvedResourceRegistration
11
+ * @property {string} modelName - Effective frontend model name (modelName override or registry key).
12
+ * @property {import("../configuration-types.js").FrontendModelResourceClassType} resourceClass - Registered resource class.
13
+ * @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration} resourceConfiguration - Normalized resource configuration.
14
+ */
8
15
  const BASE_FRONTEND_MODEL_ABILITY_ACTIONS = ["create", "destroy", "read", "update"]
9
16
  const SHA256_INITIAL_HASH = [
10
17
  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
@@ -1027,14 +1034,6 @@ function normalizeFrontendModelResourcePathForMatch(path) {
1027
1034
  return withLeadingSlash
1028
1035
  }
1029
1036
 
1030
- /**
1031
- * Resolved frontend-model resource registration for a replay resource type.
1032
- * @typedef {object} FrontendModelResolvedResourceRegistration
1033
- * @property {string} modelName - Effective frontend model name (modelName override or registry key).
1034
- * @property {import("../configuration-types.js").FrontendModelResourceClassType} resourceClass - Registered resource class.
1035
- * @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration} resourceConfiguration - Normalized resource configuration.
1036
- */
1037
-
1038
1037
  /**
1039
1038
  * Resolves the registered frontend-model resource class for a resource type
1040
1039
  * across all backend projects. A resource's effective name is its
@@ -4,28 +4,26 @@ import {resolveFrontendModelClass} from "./model-registry.js"
4
4
  import isPlainObject from "../utils/plain-object.js"
5
5
  import {formatDateInTimeZone, validateTimeZone} from "../time-zone.js"
6
6
 
7
- const TYPE_KEY = "__velocious_type"
8
- const TYPE_DATE = "date"
9
- const TYPE_UNDEFINED = "undefined"
10
- const TYPE_BIGINT = "bigint"
11
- const TYPE_NUMBER = "number"
12
- const TYPE_FRONTEND_MODEL = "frontend_model"
13
- const NUMBER_NAN = "NaN"
14
- const NUMBER_POSITIVE_INFINITY = "Infinity"
15
- const NUMBER_NEGATIVE_INFINITY = "-Infinity"
16
- const PRELOADED_RELATIONSHIPS_KEY = "__preloadedRelationships"
17
-
18
7
  /**
19
8
  * Frontend model transport serialization options.
20
9
  * @typedef {object} FrontendModelTransportSerializationOptions
21
10
  * @property {string | undefined} [timeZone] - IANA timezone used when serializing Date instants.
22
11
  */
23
-
24
12
  /**
25
13
  * Normalized frontend model transport serialization options.
26
14
  * @typedef {object} NormalizedFrontendModelTransportSerializationOptions
27
15
  * @property {string | undefined} timeZone - Validated IANA timezone used when serializing Date instants.
28
16
  */
17
+ const TYPE_KEY = "__velocious_type"
18
+ const TYPE_DATE = "date"
19
+ const TYPE_UNDEFINED = "undefined"
20
+ const TYPE_BIGINT = "bigint"
21
+ const TYPE_NUMBER = "number"
22
+ const TYPE_FRONTEND_MODEL = "frontend_model"
23
+ const NUMBER_NAN = "NaN"
24
+ const NUMBER_POSITIVE_INFINITY = "Infinity"
25
+ const NUMBER_NEGATIVE_INFINITY = "-Infinity"
26
+ const PRELOADED_RELATIONSHIPS_KEY = "__preloadedRelationships"
29
27
 
30
28
  /**
31
29
  * Assign a key to a plain object without triggering the `__proto__` setter.
@@ -4,6 +4,18 @@ import VelociousWebsocketChannel from "../http-server/websocket-channel.js"
4
4
  import Response from "../http-server/client/response.js"
5
5
  import {serializeFrontendModelTransportValue} from "./transport-serialization.js"
6
6
 
7
+ /**
8
+ * Defines this typedef.
9
+ * @typedef {{action?: string, id?: string | number, matchedEventFilterKeys?: string[], record?: import("./query.js").FrontendModelTransportValue, [key: string]: import("./query.js").FrontendModelTransportValue | string[] | undefined}} FrontendModelLifecycleBroadcastBody
10
+ */
11
+ /**
12
+ * Defines this typedef.
13
+ * @typedef {{headers?: () => Record<string, string | string[] | undefined>, remoteAddress?: () => string | undefined}} FrontendModelWebsocketUpgradeRequest
14
+ */
15
+ /**
16
+ * Defines this typedef.
17
+ * @typedef {{headers: () => Record<string, string | string[] | undefined>, header: (name: string) => string | string[] | undefined, metadata: (key?: string) => Record<string, import("./query.js").FrontendModelTransportValue> | import("./query.js").FrontendModelTransportValue | undefined, path: () => string, httpMethod: () => string, remoteAddress: () => string | undefined, origin: () => string | string[] | undefined}} FrontendModelWebsocketSyntheticRequest
18
+ */
7
19
  const EVENT_FILTER_KEYS = new Set(["joins", "key", "searches", "where"])
8
20
 
9
21
  // Mirrors FRONTEND_MODELS_CHANNEL_NAME in ./websocket-publishers.js, duplicated here
@@ -21,19 +33,6 @@ function transportSerializationOptionsForConfiguration(configuration) {
21
33
  }
22
34
  }
23
35
 
24
- /**
25
- * Defines this typedef.
26
- * @typedef {{action?: string, id?: string | number, matchedEventFilterKeys?: string[], record?: import("./query.js").FrontendModelTransportValue, [key: string]: import("./query.js").FrontendModelTransportValue | string[] | undefined}} FrontendModelLifecycleBroadcastBody
27
- */
28
- /**
29
- * Defines this typedef.
30
- * @typedef {{headers?: () => Record<string, string | string[] | undefined>, remoteAddress?: () => string | undefined}} FrontendModelWebsocketUpgradeRequest
31
- */
32
- /**
33
- * Defines this typedef.
34
- * @typedef {{headers: () => Record<string, string | string[] | undefined>, header: (name: string) => string | string[] | undefined, metadata: (key?: string) => Record<string, import("./query.js").FrontendModelTransportValue> | import("./query.js").FrontendModelTransportValue | undefined, path: () => string, httpMethod: () => string, remoteAddress: () => string | undefined, origin: () => string | string[] | undefined}} FrontendModelWebsocketSyntheticRequest
35
- */
36
-
37
36
  /**
38
37
  * Per-session channel subscription for frontend-model lifecycle events.
39
38
  * Replaces the legacy `FrontendModelWebsocketChannel` (Phase 3).
@@ -9,6 +9,10 @@ import WebsocketRequest from "./websocket-request.js"
9
9
  import WebsocketChannel from "../websocket-channel.js"
10
10
  import {websocketEventLogStoreForConfiguration} from "../websocket-event-log-store.js"
11
11
 
12
+ /**
13
+ * Defines this typedef.
14
+ * @typedef {{type: "subscribe", channel: string, lastEventId?: string, params?: Record<string, ?>} | {type: "metadata", data?: Record<string, ?>} | {type?: "request", body?: ?, headers?: Record<string, ?>, id?: string | number | null, method: string, path: string} | Record<string, ?>} WebsocketSessionMessage
15
+ */
12
16
  const WEBSOCKET_FINAL_FRAME = 0x80
13
17
  const WEBSOCKET_OPCODE_CONTINUATION = 0x0
14
18
  const WEBSOCKET_OPCODE_TEXT = 0x1
@@ -31,11 +35,6 @@ const WEBSOCKET_MAX_INBOUND_FRAME_BYTES_BIGINT = BigInt(WEBSOCKET_MAX_FINAL_FRAM
31
35
  /** Cap on fragment count for a single fragmented message. */
32
36
  const WEBSOCKET_MAX_FRAGMENTED_MESSAGE_FRAGMENTS = 1024
33
37
 
34
- /**
35
- * Defines this typedef.
36
- * @typedef {{type: "subscribe", channel: string, lastEventId?: string, params?: Record<string, ?>} | {type: "metadata", data?: Record<string, ?>} | {type?: "request", body?: ?, headers?: Record<string, ?>, id?: string | number | null, method: string, path: string} | Record<string, ?>} WebsocketSessionMessage
37
- */
38
-
39
38
  /**
40
39
  * Runs subscribe message.
41
40
  * @param {WebsocketSessionMessage} message - Raw websocket message.
@@ -1,3 +1,10 @@
1
+ /**
2
+ * @typedef {object} DeliveryTask
3
+ * @property {number} byteLength - Retained complete-buffer bytes.
4
+ * @property {boolean} countedFrame - Whether this task is an outbound frame.
5
+ * @property {() => Promise<void>} delivery - Delivery operation.
6
+ * @property {(error?: Error) => void} settle - Settles the enqueue promise.
7
+ */
1
8
  // @ts-check
2
9
 
3
10
  export class ClientDeliveryQueueOverflowError extends Error {
@@ -17,14 +24,6 @@ export class ClientDeliveryQueueOverflowError extends Error {
17
24
  }
18
25
  }
19
26
 
20
- /**
21
- * @typedef {object} DeliveryTask
22
- * @property {number} byteLength - Retained complete-buffer bytes.
23
- * @property {boolean} countedFrame - Whether this task is an outbound frame.
24
- * @property {() => Promise<void>} delivery - Delivery operation.
25
- * @property {(error?: Error) => void} settle - Settles the enqueue promise.
26
- */
27
-
28
27
  export default class ClientDeliveryQueue {
29
28
  /**
30
29
  * Builds a per-client delivery queue.
@@ -4,11 +4,6 @@ import {randomUUID} from "crypto"
4
4
  import TableData from "../database/table-data/index.js"
5
5
  import Logger from "../logger.js"
6
6
 
7
- const EVENTS_TABLE = "websocket_channel_events"
8
- const REPLAY_CHANNELS_TABLE = "websocket_replay_channels"
9
- const DEFAULT_RETENTION_MS = 10 * 60 * 1000
10
- const stores = new WeakMap()
11
-
12
7
  /**
13
8
  * WebsocketEventRow type.
14
9
  * @typedef {object} WebsocketEventRow
@@ -18,12 +13,15 @@ const stores = new WeakMap()
18
13
  * @property {string} payload_json - Serialized payload.
19
14
  * @property {number | string} sequence - Sequence number.
20
15
  */
21
-
22
16
  /**
23
17
  * WebsocketReplayChannelRow type.
24
18
  * @typedef {object} WebsocketReplayChannelRow
25
19
  * @property {string} channel - Channel name.
26
20
  */
21
+ const EVENTS_TABLE = "websocket_channel_events"
22
+ const REPLAY_CHANNELS_TABLE = "websocket_replay_channels"
23
+ const DEFAULT_RETENTION_MS = 10 * 60 * 1000
24
+ const stores = new WeakMap()
27
25
 
28
26
  /**
29
27
  * Runs the websocketEventLogStoreForConfiguration helper.
@@ -2,23 +2,21 @@ import {createRequire} from "node:module"
2
2
  import path from "node:path"
3
3
  import SqlJsWasmRouteController from "./sqljs-wasm-route-controller.js"
4
4
 
5
- const require = createRequire(import.meta.url)
6
- const sqlJsEntryPath = require.resolve("sql.js")
7
- const sqlJsDistDirectory = path.dirname(sqlJsEntryPath)
8
-
9
5
  /**
10
6
  * InstallSqlJsWasmRouteArgs type.
11
7
  * @typedef {object} InstallSqlJsWasmRouteArgs
12
8
  * @property {import("../configuration.js").default} configuration - Velocious configuration instance.
13
9
  * @property {string} [routePrefix] - Route prefix used for sql.js asset serving.
14
10
  */
15
-
16
11
  /**
17
12
  * SqlJsLocateFileFromBackendArgs type.
18
13
  * @typedef {object} SqlJsLocateFileFromBackendArgs
19
14
  * @property {string} backendBaseUrl - Backend base URL (for example `https://api.example.com`).
20
15
  * @property {string} [routePrefix] - Route prefix used for sql.js asset serving.
21
16
  */
17
+ const require = createRequire(import.meta.url)
18
+ const sqlJsEntryPath = require.resolve("sql.js")
19
+ const sqlJsDistDirectory = path.dirname(sqlJsEntryPath)
22
20
 
23
21
  /**
24
22
  * Runs normalize route prefix.
@@ -1,17 +1,11 @@
1
- // @ts-check
2
-
3
- const CONFLICT_STRATEGIES = new Set(["optimisticVersion", "serverWins", "lastWriterWins", "fieldThreeWay", "appendOnly"])
4
-
5
1
  /**
6
2
  * @typedef {null | string | number | boolean | unknown[] | Record<string, unknown>} SyncJsonValue
7
3
  */
8
-
9
4
  /**
10
5
  * @typedef {object} SyncConflictRecord
11
6
  * @property {Record<string, SyncJsonValue>} attributes - Record attributes.
12
7
  * @property {string | number | boolean | null} [version] - Record version value.
13
8
  */
14
-
15
9
  /**
16
10
  * @typedef {object} SyncConflictResult
17
11
  * @property {Record<string, SyncJsonValue>} [attributes] - Attributes to apply when replay may continue.
@@ -19,6 +13,9 @@ const CONFLICT_STRATEGIES = new Set(["optimisticVersion", "serverWins", "lastWri
19
13
  * @property {"applied" | "conflict" | "rejected"} status - Conflict decision.
20
14
  * @property {string} strategy - Strategy that produced the decision.
21
15
  */
16
+ // @ts-check
17
+
18
+ const CONFLICT_STRATEGIES = new Set(["optimisticVersion", "serverWins", "lastWriterWins", "fieldThreeWay", "appendOnly"])
22
19
 
23
20
  /**
24
21
  * Evaluates a replay mutation against server/base state using a sync conflict strategy.
@@ -1,13 +1,7 @@
1
- // @ts-check
2
-
3
- const ECDSA_P256_SHA256_ALGORITHM = "ECDSA-P256-SHA256"
4
- const ECDSA_P256_SHA256_SIGNATURE_PREFIX = "ecdsa-p256-sha256-"
5
-
6
1
  /**
7
2
  * JSON Web Key used by the sync signing helpers.
8
3
  * @typedef {import("node:crypto").webcrypto.JsonWebKey} SyncJsonWebKey
9
4
  */
10
-
11
5
  /**
12
6
  * Backend-signed device certificate payload.
13
7
  * @typedef {object} DeviceCertificatePayload
@@ -18,7 +12,6 @@ const ECDSA_P256_SHA256_SIGNATURE_PREFIX = "ecdsa-p256-sha256-"
18
12
  * @property {string} expiresAt - ISO timestamp after which the certificate is invalid.
19
13
  * @property {string} issuedAt - ISO timestamp when the backend issued the certificate.
20
14
  */
21
-
22
15
  /**
23
16
  * Backend-signed device certificate envelope.
24
17
  * @typedef {object} DeviceCertificate
@@ -26,7 +19,6 @@ const ECDSA_P256_SHA256_SIGNATURE_PREFIX = "ecdsa-p256-sha256-"
26
19
  * @property {DeviceCertificatePayload} certificate - Certificate payload.
27
20
  * @property {string} signature - Backend signature over the certificate payload.
28
21
  */
29
-
30
22
  /**
31
23
  * Sync mutation payload signed by a device.
32
24
  * @typedef {object} SyncMutation
@@ -43,7 +35,6 @@ const ECDSA_P256_SHA256_SIGNATURE_PREFIX = "ecdsa-p256-sha256-"
43
35
  * @property {Record<string, import("../configuration-types.js").FrontendModelSyncJsonValue>} [payload] - Domain command payload.
44
36
  * @property {string} policyHash - Sync policy hash the mutation was checked against.
45
37
  */
46
-
47
38
  /**
48
39
  * Device-signed mutation envelope.
49
40
  * @typedef {object} SignedSyncMutation
@@ -52,6 +43,10 @@ const ECDSA_P256_SHA256_SIGNATURE_PREFIX = "ecdsa-p256-sha256-"
52
43
  * @property {SyncMutation} mutation - Mutation payload.
53
44
  * @property {string} signature - Device signature over the mutation envelope.
54
45
  */
46
+ // @ts-check
47
+
48
+ const ECDSA_P256_SHA256_ALGORITHM = "ECDSA-P256-SHA256"
49
+ const ECDSA_P256_SHA256_SIGNATURE_PREFIX = "ecdsa-p256-sha256-"
55
50
 
56
51
  /**
57
52
  * Generates an ECDSA P-256 keypair exported as JWKs.