velocious 1.0.492 → 1.0.494

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 (35) hide show
  1. package/build/database/drivers/base.js +6 -0
  2. package/build/database/query/insert-base.js +1 -1
  3. package/build/src/database/drivers/base.d.ts +5 -0
  4. package/build/src/database/drivers/base.d.ts.map +1 -1
  5. package/build/src/database/drivers/base.js +6 -1
  6. package/build/src/database/query/insert-base.js +2 -2
  7. package/build/src/sync/server-sequence-allocator.d.ts +106 -0
  8. package/build/src/sync/server-sequence-allocator.d.ts.map +1 -0
  9. package/build/src/sync/server-sequence-allocator.js +220 -0
  10. package/build/src/sync/sync-attribute-normalizer.d.ts +105 -0
  11. package/build/src/sync/sync-attribute-normalizer.d.ts.map +1 -0
  12. package/build/src/sync/sync-attribute-normalizer.js +172 -0
  13. package/build/src/sync/sync-envelope-replay-service.d.ts +116 -7
  14. package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
  15. package/build/src/sync/sync-envelope-replay-service.js +103 -10
  16. package/build/src/sync/sync-replay-upsert-applier.d.ts +102 -0
  17. package/build/src/sync/sync-replay-upsert-applier.d.ts.map +1 -0
  18. package/build/src/sync/sync-replay-upsert-applier.js +158 -0
  19. package/build/src/sync/sync-resource-base.d.ts +48 -0
  20. package/build/src/sync/sync-resource-base.d.ts.map +1 -1
  21. package/build/src/sync/sync-resource-base.js +89 -1
  22. package/build/sync/server-sequence-allocator.js +246 -0
  23. package/build/sync/sync-attribute-normalizer.js +186 -0
  24. package/build/sync/sync-envelope-replay-service.js +114 -9
  25. package/build/sync/sync-replay-upsert-applier.js +179 -0
  26. package/build/sync/sync-resource-base.js +103 -0
  27. package/build/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +2 -2
  29. package/src/database/drivers/base.js +6 -0
  30. package/src/database/query/insert-base.js +1 -1
  31. package/src/sync/server-sequence-allocator.js +246 -0
  32. package/src/sync/sync-attribute-normalizer.js +186 -0
  33. package/src/sync/sync-envelope-replay-service.js +114 -9
  34. package/src/sync/sync-replay-upsert-applier.js +179 -0
  35. package/src/sync/sync-resource-base.js +103 -0
@@ -0,0 +1,172 @@
1
+ // @ts-check
2
+ import { snakeCaseKey } from "typanic";
3
+ /**
4
+ * Builds the error thrown for a failed sync attribute validation.
5
+ * @callback SyncAttributeErrorFactory
6
+ * @param {string} message - Human-readable validation message.
7
+ * @param {{cause?: Error, code: string}} details - Stable machine-readable code and optional cause.
8
+ * @returns {Error} Error to throw.
9
+ */
10
+ /**
11
+ * Declarative validation schema for one writable sync attribute.
12
+ *
13
+ * Keys are camelCase attribute names; each attribute also accepts its
14
+ * snake_case column key on input (the camelCase key wins when both are given)
15
+ * and is written under the snake_case column key on output. Error messages
16
+ * default to `<label> ...` phrasings with `sync-<label>-...` codes, where the
17
+ * label defaults to the camelCase attribute name; apps pin exact messages per
18
+ * attribute through the `*Message` overrides.
19
+ * @typedef {object} SyncAttributeSchemaEntry
20
+ * @property {"date" | "json" | "raw" | "string"} type - Attribute value type.
21
+ * @property {boolean} [required] - Whether present blank/absent values are rejected (strings reject blank-after-trim, dates reject null).
22
+ * @property {number} [maxLength] - Maximum string length, checked after trimming.
23
+ * @property {string} [label] - Label used in derived messages and codes.
24
+ * @property {string} [column] - Output column key. Defaults to the snake_cased attribute name.
25
+ * @property {string} [requiredMessage] - Pinned message for required rejections.
26
+ * @property {string} [tooLongMessage] - Pinned message for too-long rejections.
27
+ * @property {string} [invalidMessage] - Pinned message for invalid dates and non-object/non-string json values.
28
+ * @property {string} [invalidJsonMessage] - Pinned message for unparseable json strings.
29
+ */
30
+ /**
31
+ * Normalizes writable sync attributes against a declarative schema.
32
+ *
33
+ * Only present keys are validated, so required attributes may be absent —
34
+ * create defaults own that concern. Input keys not declared in the schema are
35
+ * rejected by default so misspelled or read-only attributes fail loudly
36
+ * instead of being silently discarded (`unknownAttributes: "ignore"` opts
37
+ * out). Validation failures throw through the given error factory so apps
38
+ * control the raised error class.
39
+ * @param {object} args - Options.
40
+ * @param {Record<string, ?>} args.attributes - Raw incoming attributes (camelCase and/or snake_case keys).
41
+ * @param {SyncAttributeErrorFactory} args.errorFactory - Maps validation failures to thrown errors.
42
+ * @param {Record<string, SyncAttributeSchemaEntry>} args.schema - Attribute schema keyed by camelCase attribute name.
43
+ * @param {"error" | "ignore"} [args.unknownAttributes] - Unknown input-key handling. Defaults to "error".
44
+ * @returns {Record<string, ?>} Normalized values keyed by snake_case column names.
45
+ */
46
+ export default function normalizeAttributesWithSchema({ attributes, errorFactory, schema, unknownAttributes = "error" }) {
47
+ if (!attributes || typeof attributes != "object")
48
+ throw new Error(`normalizeAttributesWithSchema requires an attributes object, got: ${String(attributes)}`);
49
+ if (typeof errorFactory != "function")
50
+ throw new Error("normalizeAttributesWithSchema requires an errorFactory function");
51
+ if (!schema || typeof schema != "object")
52
+ throw new Error(`normalizeAttributesWithSchema requires a schema object, got: ${String(schema)}`);
53
+ if (unknownAttributes != "error" && unknownAttributes != "ignore") {
54
+ throw new Error(`normalizeAttributesWithSchema unknownAttributes must be "error" or "ignore", got: ${String(unknownAttributes)}`);
55
+ }
56
+ /** @type {Record<string, ?>} */
57
+ const normalized = {};
58
+ /** @type {Set<string>} */
59
+ const knownInputKeys = new Set();
60
+ for (const [attributeName, entry] of Object.entries(schema)) {
61
+ const column = entry.column ?? snakeCaseKey(attributeName);
62
+ const inputKeys = column == attributeName ? [attributeName] : [column, attributeName];
63
+ for (const inputKey of inputKeys) {
64
+ knownInputKeys.add(inputKey);
65
+ if (!Object.prototype.hasOwnProperty.call(attributes, inputKey))
66
+ continue;
67
+ normalized[column] = normalizeAttributeValue({ attributeName, entry, errorFactory, value: attributes[inputKey] });
68
+ }
69
+ }
70
+ if (unknownAttributes == "error") {
71
+ for (const inputKey of Object.keys(attributes)) {
72
+ if (!knownInputKeys.has(inputKey)) {
73
+ throw errorFactory(`Unknown attribute: ${inputKey}.`, { code: "sync-unknown-attribute" });
74
+ }
75
+ }
76
+ }
77
+ return normalized;
78
+ }
79
+ /**
80
+ * Normalizes one present attribute value per its schema entry.
81
+ * @param {object} args - Options.
82
+ * @param {string} args.attributeName - camelCase attribute name.
83
+ * @param {SyncAttributeSchemaEntry} args.entry - Schema entry.
84
+ * @param {SyncAttributeErrorFactory} args.errorFactory - Error factory.
85
+ * @param {?} args.value - Raw value.
86
+ * @returns {?} Normalized value.
87
+ */
88
+ function normalizeAttributeValue({ attributeName, entry, errorFactory, value }) {
89
+ const label = entry.label ?? attributeName;
90
+ if (entry.type == "string")
91
+ return normalizeString({ entry, errorFactory, label, value });
92
+ if (entry.type == "date")
93
+ return normalizeDate({ entry, errorFactory, label, value });
94
+ if (entry.type == "json")
95
+ return normalizeJson({ entry, errorFactory, label, value });
96
+ if (entry.type == "raw")
97
+ return value;
98
+ throw new Error(`Unknown sync attribute schema type for ${attributeName}: ${String(entry.type)}`);
99
+ }
100
+ /**
101
+ * Normalizes a string attribute: trims, rejects blank required values after trimming, maps empty optional values to null and bounds the trimmed length.
102
+ * @param {object} args - Options.
103
+ * @param {SyncAttributeSchemaEntry} args.entry - Schema entry.
104
+ * @param {SyncAttributeErrorFactory} args.errorFactory - Error factory.
105
+ * @param {string} args.label - Message/code label.
106
+ * @param {?} args.value - Raw value.
107
+ * @returns {string | null} Normalized string.
108
+ */
109
+ function normalizeString({ entry, errorFactory, label, value }) {
110
+ const requiredError = () => errorFactory(entry.requiredMessage ?? `${label} is required.`, { code: `sync-${label}-required` });
111
+ if (value === null || value === undefined || value === "") {
112
+ if (entry.required)
113
+ throw requiredError();
114
+ return null;
115
+ }
116
+ const stringValue = String(value).trim();
117
+ if (stringValue === "") {
118
+ if (entry.required)
119
+ throw requiredError();
120
+ return null;
121
+ }
122
+ if (entry.maxLength !== undefined && stringValue.length > entry.maxLength) {
123
+ throw errorFactory(entry.tooLongMessage ?? `${label} is too long (maximum is ${entry.maxLength} characters).`, { code: `sync-${label}-too-long` });
124
+ }
125
+ return stringValue;
126
+ }
127
+ /**
128
+ * Normalizes a date attribute: Date instances pass through, strings/numbers are parsed and invalid or missing-required values are rejected.
129
+ * @param {object} args - Options.
130
+ * @param {SyncAttributeSchemaEntry} args.entry - Schema entry.
131
+ * @param {SyncAttributeErrorFactory} args.errorFactory - Error factory.
132
+ * @param {string} args.label - Message/code label.
133
+ * @param {?} args.value - Raw value.
134
+ * @returns {Date | null} Normalized date.
135
+ */
136
+ function normalizeDate({ entry, errorFactory, label, value }) {
137
+ if (!entry.required && (value === null || value === undefined || value === ""))
138
+ return null;
139
+ const dateValue = value instanceof Date ? value : typeof value == "string" || typeof value == "number" ? new Date(value) : null;
140
+ if (!dateValue || Number.isNaN(dateValue.getTime())) {
141
+ throw errorFactory(entry.invalidMessage ?? `${label} must be a valid datetime.`, { code: `sync-${label}-invalid-datetime` });
142
+ }
143
+ return dateValue;
144
+ }
145
+ /**
146
+ * Normalizes a json attribute: empty values become null, objects pass through, strings must parse as JSON and other types are rejected.
147
+ * @param {object} args - Options.
148
+ * @param {SyncAttributeSchemaEntry} args.entry - Schema entry.
149
+ * @param {SyncAttributeErrorFactory} args.errorFactory - Error factory.
150
+ * @param {string} args.label - Message/code label.
151
+ * @param {?} args.value - Raw value.
152
+ * @returns {?} Normalized json value.
153
+ */
154
+ function normalizeJson({ entry, errorFactory, label, value }) {
155
+ if (value === null || value === undefined || value === "")
156
+ return null;
157
+ if (typeof value == "object")
158
+ return value;
159
+ if (typeof value == "string") {
160
+ try {
161
+ return JSON.parse(value);
162
+ }
163
+ catch (error) {
164
+ throw errorFactory(entry.invalidJsonMessage ?? `${label} must be valid JSON.`, {
165
+ cause: /** @type {Error} */ (error),
166
+ code: `sync-${label}-invalid-json`
167
+ });
168
+ }
169
+ }
170
+ throw errorFactory(entry.invalidMessage ?? `${label} must be an object or JSON string.`, { code: `sync-${label}-invalid` });
171
+ }
172
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1hdHRyaWJ1dGUtbm9ybWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtYXR0cmlidXRlLW5vcm1hbGl6ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFFcEM7Ozs7OztHQU1HO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFFSDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLENBQUMsT0FBTyxVQUFVLDZCQUE2QixDQUFDLEVBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEdBQUcsT0FBTyxFQUFDO0lBQ25ILElBQUksQ0FBQyxVQUFVLElBQUksT0FBTyxVQUFVLElBQUksUUFBUTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUVBQXFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDNUosSUFBSSxPQUFPLFlBQVksSUFBSSxVQUFVO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpRUFBaUUsQ0FBQyxDQUFBO0lBQ3pILElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLElBQUksUUFBUTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDM0ksSUFBSSxpQkFBaUIsSUFBSSxPQUFPLElBQUksaUJBQWlCLElBQUksUUFBUSxFQUFFLENBQUM7UUFDbEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxRkFBcUYsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ25JLENBQUM7SUFFRCxnQ0FBZ0M7SUFDaEMsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFBO0lBQ3JCLDBCQUEwQjtJQUMxQixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBRWhDLEtBQUssTUFBTSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDNUQsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUE7UUFDMUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUE7UUFFckYsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNqQyxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBRTVCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQztnQkFBRSxTQUFRO1lBRXpFLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyx1QkFBdUIsQ0FBQyxFQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUMsQ0FBQyxDQUFBO1FBQ2pILENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxpQkFBaUIsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNqQyxLQUFLLE1BQU0sUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLFlBQVksQ0FBQyxzQkFBc0IsUUFBUSxHQUFHLEVBQUUsRUFBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUMsQ0FBQyxDQUFBO1lBQ3pGLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sVUFBVSxDQUFBO0FBQ25CLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsdUJBQXVCLENBQUMsRUFBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUM7SUFDMUUsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssSUFBSSxhQUFhLENBQUE7SUFFMUMsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLFFBQVE7UUFBRSxPQUFPLGVBQWUsQ0FBQyxFQUFDLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7SUFDdkYsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLE1BQU07UUFBRSxPQUFPLGFBQWEsQ0FBQyxFQUFDLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7SUFDbkYsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLE1BQU07UUFBRSxPQUFPLGFBQWEsQ0FBQyxFQUFDLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7SUFDbkYsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUs7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUVyQyxNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxhQUFhLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDbkcsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxlQUFlLENBQUMsRUFBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUM7SUFDMUQsTUFBTSxhQUFhLEdBQUcsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxlQUFlLElBQUksR0FBRyxLQUFLLGVBQWUsRUFBRSxFQUFDLElBQUksRUFBRSxRQUFRLEtBQUssV0FBVyxFQUFDLENBQUMsQ0FBQTtJQUU1SCxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDMUQsSUFB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LWNoZWNrXG5cbmltcG9ydCB7c25ha2VDYXNlS2V5fSBmcm9tIFwidHlwYW5pY1wiXG5cbi8qKlxuICogQnVpbGRzIHRoZSBlcnJvciB0aHJvd24gZm9yIGEgZmFpbGVkIHN5bmMgYXR0cmlidXRlIHZhbGlkYXRpb24uXG4gKiBAY2FsbGJhY2sgU3luY0F0dHJpYnV0ZUVycm9yRmFjdG9yeVxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSB2YWxpZGF0aW9uIG1lc3NhZ2UuXG4gKiBAcGFyYW0ge3tjYXVzZT86IEVycm9yLCBjb2RlOiBzdHJpbmd9fSBkZXRhaWxzIC0gU3RhYmxlIG1hY2hpbmUtcmVhZGFibGUgY29kZSBhbmQgb3B0aW9uYWwgY2F1c2UuXG4gKiBAcmV0dXJucyB7RXJyb3J9IEVycm9yIHRvIHRocm93LlxuICovXG5cbi8qKlxuICogRGVjbGFyYXRpdmUgdmFsaWRhdGlvbiBzY2hlbWEgZm9yIG9uZSB3cml0YWJsZSBzeW5jIGF0dHJpYnV0ZS5cbiAqXG4gKiBLZXlzIGFyZSBjYW1lbENhc2UgYXR0cmlidXRlIG5hbWVzOyBlYWNoIGF0dHJpYnV0ZSBhbHNvIGFjY2VwdHMgaXRzXG4gKiBzbmFrZV9jYXNlIGNvbHVtbiBrZXkgb24gaW5wdXQgKHRoZSBjYW1lbENhc2Uga2V5IHdpbnMgd2hlbiBib3RoIGFyZSBnaXZlbilcbiAqIGFuZCBpcyB3cml0dGVuIHVuZGVyIHRoZSBzbmFrZV9jYXNlIGNvbHVtbiBrZXkgb24gb3V0cHV0LiBFcnJvciBtZXNzYWdlc1xuICogZGVmYXVsdCB0byBgPGxhYmVsPiAuLi5gIHBocmFzaW5ncyB3aXRoIGBzeW5jLTxsYWJlbD4tLi4uYCBjb2Rlcywgd2hlcmUgdGhlXG4gKiBsYWJlbCBkZWZhdWx0cyB0byB0aGUgY2FtZWxDYXNlIGF0dHJpYnV0ZSBuYW1lOyBhcHBzIHBpbiBleGFjdCBtZXNzYWdlcyBwZXJcbiAqIGF0dHJpYnV0ZSB0aHJvdWdoIHRoZSBgKk1lc3NhZ2VgIG92ZXJyaWRlcy5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFN5bmNBdHRyaWJ1dGVTY2hlbWFFbnRyeVxuICogQHByb3BlcnR5IHtcImRhdGVcIiB8IFwianNvblwiIHwgXCJyYXdcIiB8IFwic3RyaW5nXCJ9IHR5cGUgLSBBdHRyaWJ1dGUgdmFsdWUgdHlwZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3JlcXVpcmVkXSAtIFdoZXRoZXIgcHJlc2VudCBibGFuay9hYnNlbnQgdmFsdWVzIGFyZSByZWplY3RlZCAoc3RyaW5ncyByZWplY3QgYmxhbmstYWZ0ZXItdHJpbSwgZGF0ZXMgcmVqZWN0IG51bGwpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhMZW5ndGhdIC0gTWF4aW11bSBzdHJpbmcgbGVuZ3RoLCBjaGVja2VkIGFmdGVyIHRyaW1taW5nLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtsYWJlbF0gLSBMYWJlbCB1c2VkIGluIGRlcml2ZWQgbWVzc2FnZXMgYW5kIGNvZGVzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjb2x1bW5dIC0gT3V0cHV0IGNvbHVtbiBrZXkuIERlZmF1bHRzIHRvIHRoZSBzbmFrZV9jYXNlZCBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbcmVxdWlyZWRNZXNzYWdlXSAtIFBpbm5lZCBtZXNzYWdlIGZvciByZXF1aXJlZCByZWplY3Rpb25zLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt0b29Mb25nTWVzc2FnZV0gLSBQaW5uZWQgbWVzc2FnZSBmb3IgdG9vLWxvbmcgcmVqZWN0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbaW52YWxpZE1lc3NhZ2VdIC0gUGlubmVkIG1lc3NhZ2UgZm9yIGludmFsaWQgZGF0ZXMgYW5kIG5vbi1vYmplY3Qvbm9uLXN0cmluZyBqc29uIHZhbHVlcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbaW52YWxpZEpzb25NZXNzYWdlXSAtIFBpbm5lZCBtZXNzYWdlIGZvciB1bnBhcnNlYWJsZSBqc29uIHN0cmluZ3MuXG4gKi9cblxuLyoqXG4gKiBOb3JtYWxpemVzIHdyaXRhYmxlIHN5bmMgYXR0cmlidXRlcyBhZ2FpbnN0IGEgZGVjbGFyYXRpdmUgc2NoZW1hLlxuICpcbiAqIE9ubHkgcHJlc2VudCBrZXlzIGFyZSB2YWxpZGF0ZWQsIHNvIHJlcXVpcmVkIGF0dHJpYnV0ZXMgbWF5IGJlIGFic2VudCDigJRcbiAqIGNyZWF0ZSBkZWZhdWx0cyBvd24gdGhhdCBjb25jZXJuLiBJbnB1dCBrZXlzIG5vdCBkZWNsYXJlZCBpbiB0aGUgc2NoZW1hIGFyZVxuICogcmVqZWN0ZWQgYnkgZGVmYXVsdCBzbyBtaXNzcGVsbGVkIG9yIHJlYWQtb25seSBhdHRyaWJ1dGVzIGZhaWwgbG91ZGx5XG4gKiBpbnN0ZWFkIG9mIGJlaW5nIHNpbGVudGx5IGRpc2NhcmRlZCAoYHVua25vd25BdHRyaWJ1dGVzOiBcImlnbm9yZVwiYCBvcHRzXG4gKiBvdXQpLiBWYWxpZGF0aW9uIGZhaWx1cmVzIHRocm93IHRocm91Z2ggdGhlIGdpdmVuIGVycm9yIGZhY3Rvcnkgc28gYXBwc1xuICogY29udHJvbCB0aGUgcmFpc2VkIGVycm9yIGNsYXNzLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy5hdHRyaWJ1dGVzIC0gUmF3IGluY29taW5nIGF0dHJpYnV0ZXMgKGNhbWVsQ2FzZSBhbmQvb3Igc25ha2VfY2FzZSBrZXlzKS5cbiAqIEBwYXJhbSB7U3luY0F0dHJpYnV0ZUVycm9yRmFjdG9yeX0gYXJncy5lcnJvckZhY3RvcnkgLSBNYXBzIHZhbGlkYXRpb24gZmFpbHVyZXMgdG8gdGhyb3duIGVycm9ycy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgU3luY0F0dHJpYnV0ZVNjaGVtYUVudHJ5Pn0gYXJncy5zY2hlbWEgLSBBdHRyaWJ1dGUgc2NoZW1hIGtleWVkIGJ5IGNhbWVsQ2FzZSBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwYXJhbSB7XCJlcnJvclwiIHwgXCJpZ25vcmVcIn0gW2FyZ3MudW5rbm93bkF0dHJpYnV0ZXNdIC0gVW5rbm93biBpbnB1dC1rZXkgaGFuZGxpbmcuIERlZmF1bHRzIHRvIFwiZXJyb3JcIi5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gTm9ybWFsaXplZCB2YWx1ZXMga2V5ZWQgYnkgc25ha2VfY2FzZSBjb2x1bW4gbmFtZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG5vcm1hbGl6ZUF0dHJpYnV0ZXNXaXRoU2NoZW1hKHthdHRyaWJ1dGVzLCBlcnJvckZhY3RvcnksIHNjaGVtYSwgdW5rbm93bkF0dHJpYnV0ZXMgPSBcImVycm9yXCJ9KSB7XG4gIGlmICghYXR0cmlidXRlcyB8fCB0eXBlb2YgYXR0cmlidXRlcyAhPSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgRXJyb3IoYG5vcm1hbGl6ZUF0dHJpYnV0ZXNXaXRoU2NoZW1hIHJlcXVpcmVzIGFuIGF0dHJpYnV0ZXMgb2JqZWN0LCBnb3Q6ICR7U3RyaW5nKGF0dHJpYnV0ZXMpfWApXG4gIGlmICh0eXBlb2YgZXJyb3JGYWN0b3J5ICE9IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKFwibm9ybWFsaXplQXR0cmlidXRlc1dpdGhTY2hlbWEgcmVxdWlyZXMgYW4gZXJyb3JGYWN0b3J5IGZ1bmN0aW9uXCIpXG4gIGlmICghc2NoZW1hIHx8IHR5cGVvZiBzY2hlbWEgIT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IEVycm9yKGBub3JtYWxpemVBdHRyaWJ1dGVzV2l0aFNjaGVtYSByZXF1aXJlcyBhIHNjaGVtYSBvYmplY3QsIGdvdDogJHtTdHJpbmcoc2NoZW1hKX1gKVxuICBpZiAodW5rbm93bkF0dHJpYnV0ZXMgIT0gXCJlcnJvclwiICYmIHVua25vd25BdHRyaWJ1dGVzICE9IFwiaWdub3JlXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vcm1hbGl6ZUF0dHJpYnV0ZXNXaXRoU2NoZW1hIHVua25vd25BdHRyaWJ1dGVzIG11c3QgYmUgXCJlcnJvclwiIG9yIFwiaWdub3JlXCIsIGdvdDogJHtTdHJpbmcodW5rbm93bkF0dHJpYnV0ZXMpfWApXG4gIH1cblxuICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqL1xuICBjb25zdCBub3JtYWxpemVkID0ge31cbiAgLyoqIEB0eXBlIHtTZXQ8c3RyaW5nPn0gKi9cbiAgY29uc3Qga25vd25JbnB1dEtleXMgPSBuZXcgU2V0KClcblxuICBmb3IgKGNvbnN0IFthdHRyaWJ1dGVOYW1lLCBlbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMoc2NoZW1hKSkge1xuICAgIGNvbnN0IGNvbHVtbiA9IGVudHJ5LmNvbHVtbiA/PyBzbmFrZUNhc2VLZXkoYXR0cmlidXRlTmFtZSlcbiAgICBjb25zdCBpbnB1dEtleXMgPSBjb2x1bW4gPT0gYXR0cmlidXRlTmFtZSA/IFthdHRyaWJ1dGVOYW1lXSA6IFtjb2x1bW4sIGF0dHJpYnV0ZU5hbWVdXG5cbiAgICBmb3IgKGNvbnN0IGlucHV0S2V5IG9mIGlucHV0S2V5cykge1xuICAgICAga25vd25JbnB1dEtleXMuYWRkKGlucHV0S2V5KVxuXG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhdHRyaWJ1dGVzLCBpbnB1dEtleSkpIGNvbnRpbnVlXG5cbiAgICAgIG5vcm1hbGl6ZWRbY29sdW1uXSA9IG5vcm1hbGl6ZUF0dHJpYnV0ZVZhbHVlKHthdHRyaWJ1dGVOYW1lLCBlbnRyeSwgZXJyb3JGYWN0b3J5LCB2YWx1ZTogYXR0cmlidXRlc1tpbnB1dEtleV19KVxuICAgIH1cbiAgfVxuXG4gIGlmICh1bmtub3duQXR0cmlidXRlcyA9PSBcImVycm9yXCIpIHtcbiAgICBmb3IgKGNvbnN0IGlucHV0S2V5IG9mIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpKSB7XG4gICAgICBpZiAoIWtub3duSW5wdXRLZXlzLmhhcyhpbnB1dEtleSkpIHtcbiAgICAgICAgdGhyb3cgZXJyb3JGYWN0b3J5KGBVbmtub3duIGF0dHJpYnV0ZTogJHtpbnB1dEtleX0uYCwge2NvZGU6IFwic3luYy11bmtub3duLWF0dHJpYnV0ZVwifSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbm9ybWFsaXplZFxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgb25lIHByZXNlbnQgYXR0cmlidXRlIHZhbHVlIHBlciBpdHMgc2NoZW1hIGVudHJ5LlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXR0cmlidXRlTmFtZSAtIGNhbWVsQ2FzZSBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwYXJhbSB7U3luY0F0dHJpYnV0ZVNjaGVtYUVudHJ5fSBhcmdzLmVudHJ5IC0gU2NoZW1hIGVudHJ5LlxuICogQHBhcmFtIHtTeW5jQXR0cmlidXRlRXJyb3JGYWN0b3J5fSBhcmdzLmVycm9yRmFjdG9yeSAtIEVycm9yIGZhY3RvcnkuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBSYXcgdmFsdWUuXG4gKiBAcmV0dXJucyB7P30gTm9ybWFsaXplZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplQXR0cmlidXRlVmFsdWUoe2F0dHJpYnV0ZU5hbWUsIGVudHJ5LCBlcnJvckZhY3RvcnksIHZhbHVlfSkge1xuICBjb25zdCBsYWJlbCA9IGVudHJ5LmxhYmVsID8/IGF0dHJpYnV0ZU5hbWVcblxuICBpZiAoZW50cnkudHlwZSA9PSBcInN0cmluZ1wiKSByZXR1cm4gbm9ybWFsaXplU3RyaW5nKHtlbnRyeSwgZXJyb3JGYWN0b3J5LCBsYWJlbCwgdmFsdWV9KVxuICBpZiAoZW50cnkudHlwZSA9PSBcImRhdGVcIikgcmV0dXJuIG5vcm1hbGl6ZURhdGUoe2VudHJ5LCBlcnJvckZhY3RvcnksIGxhYmVsLCB2YWx1ZX0pXG4gIGlmIChlbnRyeS50eXBlID09IFwianNvblwiKSByZXR1cm4gbm9ybWFsaXplSnNvbih7ZW50cnksIGVycm9yRmFjdG9yeSwgbGFiZWwsIHZhbHVlfSlcbiAgaWYgKGVudHJ5LnR5cGUgPT0gXCJyYXdcIikgcmV0dXJuIHZhbHVlXG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHN5bmMgYXR0cmlidXRlIHNjaGVtYSB0eXBlIGZvciAke2F0dHJpYnV0ZU5hbWV9OiAke1N0cmluZyhlbnRyeS50eXBlKX1gKVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBzdHJpbmcgYXR0cmlidXRlOiB0cmltcywgcmVqZWN0cyBibGFuayByZXF1aXJlZCB2YWx1ZXMgYWZ0ZXIgdHJpbW1pbmcsIG1hcHMgZW1wdHkgb3B0aW9uYWwgdmFsdWVzIHRvIG51bGwgYW5kIGJvdW5kcyB0aGUgdHJpbW1lZCBsZW5ndGguXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1N5bmNBdHRyaWJ1dGVTY2hlbWFFbnRyeX0gYXJncy5lbnRyeSAtIFNjaGVtYSBlbnRyeS5cbiAqIEBwYXJhbSB7U3luY0F0dHJpYnV0ZUVycm9yRmFjdG9yeX0gYXJncy5lcnJvckZhY3RvcnkgLSBFcnJvciBmYWN0b3J5LlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGFiZWwgLSBNZXNzYWdlL2NvZGUgbGFiZWwuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBSYXcgdmFsdWUuXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH0gTm9ybWFsaXplZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZyh7ZW50cnksIGVycm9yRmFjdG9yeSwgbGFiZWwsIHZhbHVlfSkge1xuICBjb25zdCByZXF1aXJlZEVycm9yID0gKCkgPT4gZXJyb3JGYWN0b3J5KGVudHJ5LnJlcXVpcmVkTWVzc2FnZSA/PyBgJHtsYWJlbH0gaXMgcmVxdWlyZWQuYCwge2NvZGU6IGBzeW5jLSR7bGFiZWx9LXJlcXVpcmVkYH0pXG5cbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IFwiXCIpIHtcbiAgICBpZiAoZW50cnkucmVxdWlyZWQpIHRocm93IHJlcXVpcmVkRXJyb3IoKVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IHN0cmluZ1ZhbHVlID0gU3RyaW5nKHZhbHVlKS50cmltKClcblxuICBpZiAoc3RyaW5nVmFsdWUgPT09IFwiXCIpIHtcbiAgICBpZiAoZW50cnkucmVxdWlyZWQpIHRocm93IHJlcXVpcmVkRXJyb3IoKVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGlmIChlbnRyeS5tYXhMZW5ndGggIT09IHVuZGVmaW5lZCAmJiBzdHJpbmdWYWx1ZS5sZW5ndGggPiBlbnRyeS5tYXhMZW5ndGgpIHtcbiAgICB0aHJvdyBlcnJvckZhY3RvcnkoZW50cnkudG9vTG9uZ01lc3NhZ2UgPz8gYCR7bGFiZWx9IGlzIHRvbyBsb25nIChtYXhpbXVtIGlzICR7ZW50cnkubWF4TGVuZ3RofSBjaGFyYWN0ZXJzKS5gLCB7Y29kZTogYHN5bmMtJHtsYWJlbH0tdG9vLWxvbmdgfSlcbiAgfVxuXG4gIHJldHVybiBzdHJpbmdWYWx1ZVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBkYXRlIGF0dHJpYnV0ZTogRGF0ZSBpbnN0YW5jZXMgcGFzcyB0aHJvdWdoLCBzdHJpbmdzL251bWJlcnMgYXJlIHBhcnNlZCBhbmQgaW52YWxpZCBvciBtaXNzaW5nLXJlcXVpcmVkIHZhbHVlcyBhcmUgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1N5bmNBdHRyaWJ1dGVTY2hlbWFFbnRyeX0gYXJncy5lbnRyeSAtIFNjaGVtYSBlbnRyeS5cbiAqIEBwYXJhbSB7U3luY0F0dHJpYnV0ZUVycm9yRmFjdG9yeX0gYXJncy5lcnJvckZhY3RvcnkgLSBFcnJvciBmYWN0b3J5LlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGFiZWwgLSBNZXNzYWdlL2NvZGUgbGFiZWwuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBSYXcgdmFsdWUuXG4gKiBAcmV0dXJucyB7RGF0ZSB8IG51bGx9IE5vcm1hbGl6ZWQgZGF0ZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRGF0ZSh7ZW50cnksIGVycm9yRmFjdG9yeSwgbGFiZWwsIHZhbHVlfSkge1xuICBpZiAoIWVudHJ5LnJlcXVpcmVkICYmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBcIlwiKSkgcmV0dXJuIG51bGxcblxuICBjb25zdCBkYXRlVmFsdWUgPSB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgPyB2YWx1ZSA6IHR5cGVvZiB2YWx1ZSA9PSBcInN0cmluZ1wiIHx8IHR5cGVvZiB2YWx1ZSA9PSBcIm51bWJlclwiID8gbmV3IERhdGUodmFsdWUpIDogbnVsbFxuXG4gIGlmICghZGF0ZVZhbHVlIHx8IE51bWJlci5pc05hTihkYXRlVmFsdWUuZ2V0VGltZSgpKSkge1xuICAgIHRocm93IGVycm9yRmFjdG9yeShlbnRyeS5pbnZhbGlkTWVzc2FnZSA/PyBgJHtsYWJlbH0gbXVzdCBiZSBhIHZhbGlkIGRhdGV0aW1lLmAsIHtjb2RlOiBgc3luYy0ke2xhYmVsfS1pbnZhbGlkLWRhdGV0aW1lYH0pXG4gIH1cblxuICByZXR1cm4gZGF0ZVZhbHVlXG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIGpzb24gYXR0cmlidXRlOiBlbXB0eSB2YWx1ZXMgYmVjb21lIG51bGwsIG9iamVjdHMgcGFzcyB0aHJvdWdoLCBzdHJpbmdzIG11c3QgcGFyc2UgYXMgSlNPTiBhbmQgb3RoZXIgdHlwZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtTeW5jQXR0cmlidXRlU2NoZW1hRW50cnl9IGFyZ3MuZW50cnkgLSBTY2hlbWEgZW50cnkuXG4gKiBAcGFyYW0ge1N5bmNBdHRyaWJ1dGVFcnJvckZhY3Rvcnl9IGFyZ3MuZXJyb3JGYWN0b3J5IC0gRXJyb3IgZmFjdG9yeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmxhYmVsIC0gTWVzc2FnZS9jb2RlIGxhYmVsLlxuICogQHBhcmFtIHs/fSBhcmdzLnZhbHVlIC0gUmF3IHZhbHVlLlxuICogQHJldHVybnMgez99IE5vcm1hbGl6ZWQganNvbiB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplSnNvbih7ZW50cnksIGVycm9yRmFjdG9yeSwgbGFiZWwsIHZhbHVlfSkge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gXCJcIikgcmV0dXJuIG51bGxcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiKSByZXR1cm4gdmFsdWVcblxuICBpZiAodHlwZW9mIHZhbHVlID09IFwic3RyaW5nXCIpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGVycm9yRmFjdG9yeShlbnRyeS5pbnZhbGlkSnNvbk1lc3NhZ2UgPz8gYCR7bGFiZWx9IG11c3QgYmUgdmFsaWQgSlNPTi5gLCB7XG4gICAgICAgIGNhdXNlOiAvKiogQHR5cGUge0Vycm9yfSAqLyAoZXJyb3IpLFxuICAgICAgICBjb2RlOiBgc3luYy0ke2xhYmVsfS1pbnZhbGlkLWpzb25gXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIHRocm93IGVycm9yRmFjdG9yeShlbnRyeS5pbnZhbGlkTWVzc2FnZSA/PyBgJHtsYWJlbH0gbXVzdCBiZSBhbiBvYmplY3Qgb3IgSlNPTiBzdHJpbmcuYCwge2NvZGU6IGBzeW5jLSR7bGFiZWx9LWludmFsaWRgfSlcbn1cbiJdfQ==
@@ -1,3 +1,11 @@
1
+ /**
2
+ * One declarative broadcast fanned out after a mutation applies.
3
+ * @typedef {object} SyncReplayBroadcast
4
+ * @property {string | ((args: Record<string, ?>) => string)} channel - Channel name or resolver.
5
+ * @property {(args: Record<string, ?>) => Record<string, ?>} broadcastParams - Channel routing params.
6
+ * @property {(args: Record<string, ?>) => ?} body - Broadcast body.
7
+ * @property {(args: Record<string, ?>) => boolean} [when] - Optional gate; skipped when it returns false.
8
+ */
1
9
  /**
2
10
  * Replays client sync envelopes through project supplied authentication,
3
11
  * authorization, application, and persistence hooks.
@@ -21,6 +29,14 @@ export default class SyncEnvelopeReplayService {
21
29
  * @param {{debug?: (...args: Array<unknown>) => void, warn?: (...args: Array<unknown>) => void}} [args.logger] - Logger used for normalization warnings.
22
30
  * @param {?} [args.syncModel] - Sync/change model enabling model-backed default hooks.
23
31
  * @param {string} [args.actorForeignKeyColumn] - Sync model column linking rows to the replay actor.
32
+ * @param {?} [args.authenticationTokenModel] - Token model enabling the default token-lookup authenticateReplay.
33
+ * @param {string} [args.authenticationTokenColumn] - Token model column holding the token. Defaults to "token".
34
+ * @param {string} [args.authenticationTokenParam] - Request param carrying the token. Defaults to "authenticationToken".
35
+ * @param {Record<string, ((args: Record<string, ?>) => Promise<?>) | ConstructorParameters<typeof SyncReplayUpsertApplier>[0]>} [args.applyHandlers] - Per-resourceType apply handlers (functions or declarative upsert-applier specs) enabling the default applyReplayMutation dispatch.
36
+ * @param {(args: Record<string, ?>) => Record<string, ?>} [args.persistExtraAttributes] - Extra attributes merged into the model-backed persisted row (e.g. an event scope column).
37
+ * @param {(args: {mutation: ?, applyResult: ?}) => ?} [args.persistSerializedData] - Overrides the persisted data payload (object results are JSON stringified).
38
+ * @param {(broadcast: {channel: string, params: Record<string, ?>, body: ?}) => Promise<void>} [args.broadcaster] - Delivers declarative broadcasts. Required when broadcasts are configured.
39
+ * @param {SyncReplayBroadcast[]} [args.broadcasts] - Broadcasts fanned out by the default afterReplayMutation.
24
40
  */
25
41
  constructor(args?: {
26
42
  logger?: {
@@ -29,6 +45,48 @@ export default class SyncEnvelopeReplayService {
29
45
  } | undefined;
30
46
  syncModel?: unknown;
31
47
  actorForeignKeyColumn?: string | undefined;
48
+ authenticationTokenModel?: unknown;
49
+ authenticationTokenColumn?: string | undefined;
50
+ authenticationTokenParam?: string | undefined;
51
+ applyHandlers?: Record<string, {
52
+ modelClass: unknown;
53
+ fields: Record<string, string | {
54
+ type: string;
55
+ column?: string;
56
+ } | ((value: unknown, label: string) => unknown)>;
57
+ findRecord?: ((args: {
58
+ data: Record<string, unknown>;
59
+ mutation: unknown;
60
+ context: Record<string, unknown>;
61
+ }) => Promise<unknown>) | undefined;
62
+ findRecordForDelete?: ((args: {
63
+ mutation: unknown;
64
+ context: Record<string, unknown>;
65
+ }) => Promise<unknown>) | undefined;
66
+ restArgs?: "error" | "ignore" | undefined;
67
+ afterApply?: ((args: {
68
+ mappedAttributes: Record<string, unknown>;
69
+ mutation: unknown;
70
+ context: Record<string, unknown>;
71
+ record: unknown;
72
+ }) => Promise<Record<string, unknown> | void>) | undefined;
73
+ serialize?: ((args: {
74
+ mutation: unknown;
75
+ context: Record<string, unknown>;
76
+ record: unknown;
77
+ }) => Promise<Record<string, unknown>> | Record<string, unknown>) | undefined;
78
+ } | ((args: Record<string, unknown>) => Promise<unknown>)> | undefined;
79
+ persistExtraAttributes?: ((args: Record<string, unknown>) => Record<string, unknown>) | undefined;
80
+ persistSerializedData?: ((args: {
81
+ mutation: unknown;
82
+ applyResult: unknown;
83
+ }) => unknown) | undefined;
84
+ broadcaster?: ((broadcast: {
85
+ channel: string;
86
+ params: Record<string, unknown>;
87
+ body: unknown;
88
+ }) => Promise<void>) | undefined;
89
+ broadcasts?: SyncReplayBroadcast[] | undefined;
32
90
  });
33
91
  logger: {
34
92
  debug?: (...args: Array<unknown>) => void;
@@ -36,6 +94,27 @@ export default class SyncEnvelopeReplayService {
36
94
  };
37
95
  syncModel: any;
38
96
  actorForeignKeyColumn: string;
97
+ authenticationTokenModel: any;
98
+ authenticationTokenColumn: string;
99
+ authenticationTokenParam: string;
100
+ persistExtraAttributes: ((args: Record<string, unknown>) => Record<string, unknown>) | null;
101
+ persistSerializedData: ((args: {
102
+ mutation: unknown;
103
+ applyResult: unknown;
104
+ }) => unknown) | null;
105
+ broadcaster: ((broadcast: {
106
+ channel: string;
107
+ params: Record<string, unknown>;
108
+ body: unknown;
109
+ }) => Promise<void>) | null;
110
+ broadcasts: SyncReplayBroadcast[] | null;
111
+ applyHandlers: Record<string, (args: Record<string, unknown>) => Promise<unknown>> | null;
112
+ /**
113
+ * Wraps declarative apply-handler specs in upsert appliers.
114
+ * @param {Record<string, ?>} applyHandlers - Raw apply handlers.
115
+ * @returns {Record<string, (args: Record<string, ?>) => Promise<?>>} Callable handlers by resource type.
116
+ */
117
+ builtApplyHandlers(applyHandlers: Record<string, unknown>): Record<string, (args: Record<string, unknown>) => Promise<unknown>>;
39
118
  /**
40
119
  * Replays a sync batch.
41
120
  * @param {Record<string, ?>} params - Request params carrying authentication and syncs.
@@ -49,10 +128,13 @@ export default class SyncEnvelopeReplayService {
49
128
  }>;
50
129
  /**
51
130
  * Authenticates the sync batch actor.
52
- * @param {Record<string, ?>} _params - Request params.
131
+ *
132
+ * Defaults to a token-model lookup when `authenticationTokenModel` is
133
+ * configured; otherwise apps override this hook.
134
+ * @param {Record<string, ?>} params - Request params.
53
135
  * @returns {Promise<{authenticated: true, actor: ?} | {authenticated: false, errorCode: string, errorMessage: string}>} Auth result.
54
136
  */
55
- authenticateReplay(_params: Record<string, unknown>): Promise<{
137
+ authenticateReplay(params: Record<string, unknown>): Promise<{
56
138
  authenticated: true;
57
139
  actor: unknown;
58
140
  } | {
@@ -155,10 +237,13 @@ export default class SyncEnvelopeReplayService {
155
237
  existingReplaySyncClientUpdatedAt(existingSync: unknown): Date | null;
156
238
  /**
157
239
  * Applies one normalized mutation to domain models.
158
- * @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} _args - Actor, batch context, existing sync row, and mutation.
240
+ *
241
+ * Defaults to dispatching through the configured apply-handler registry;
242
+ * mutations without a registered handler fail loudly.
243
+ * @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Actor, batch context, existing sync row, and mutation.
159
244
  * @returns {Promise<?>} Project-specific apply result.
160
245
  */
161
- applyReplayMutation(_args: {
246
+ applyReplayMutation(args: {
162
247
  actor: unknown;
163
248
  context: Record<string, unknown>;
164
249
  existingSync: unknown;
@@ -183,7 +268,7 @@ export default class SyncEnvelopeReplayService {
183
268
  * @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} args - Replay persistence arguments.
184
269
  * @returns {Promise<void>}
185
270
  */
186
- persistReplayMutation({ actor, existingSync, mutation }: {
271
+ persistReplayMutation({ actor, applyResult, context, existingSync, mutation, shouldApply }: {
187
272
  actor: unknown;
188
273
  context: Record<string, unknown>;
189
274
  existingSync: unknown;
@@ -202,10 +287,13 @@ export default class SyncEnvelopeReplayService {
202
287
  }): Record<string, unknown>;
203
288
  /**
204
289
  * Runs side effects after a successful mutation replay and persistence.
205
- * @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} _args - Replay side-effect arguments.
290
+ *
291
+ * Defaults to fanning the applied result out through the configured
292
+ * declarative broadcasts.
293
+ * @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} args - Replay side-effect arguments.
206
294
  * @returns {Promise<void>}
207
295
  */
208
- afterReplayMutation(_args: {
296
+ afterReplayMutation(args: {
209
297
  actor: unknown;
210
298
  context: Record<string, unknown>;
211
299
  existingSync: unknown;
@@ -214,6 +302,27 @@ export default class SyncEnvelopeReplayService {
214
302
  shouldApply: boolean;
215
303
  }): Promise<void>;
216
304
  }
305
+ /**
306
+ * One declarative broadcast fanned out after a mutation applies.
307
+ */
308
+ export type SyncReplayBroadcast = {
309
+ /**
310
+ * - Channel name or resolver.
311
+ */
312
+ channel: string | ((args: Record<string, unknown>) => string);
313
+ /**
314
+ * - Channel routing params.
315
+ */
316
+ broadcastParams: (args: Record<string, unknown>) => Record<string, unknown>;
317
+ /**
318
+ * - Broadcast body.
319
+ */
320
+ body: (args: Record<string, unknown>) => unknown;
321
+ /**
322
+ * - Optional gate; skipped when it returns false.
323
+ */
324
+ when?: ((args: Record<string, unknown>) => boolean) | undefined;
325
+ };
217
326
  export type SyncReplayMutation = {
218
327
  /**
219
328
  * - Client-side mutation timestamp.
@@ -1 +1 @@
1
- {"version":3,"file":"sync-envelope-replay-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-envelope-replay-service.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-envelope-replay-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-envelope-replay-service.js"],"names":[],"mappings":"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"}