@researchdatabox/sails-ng-common 5.0.3 → 5.0.4-beta.12498

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 (60) hide show
  1. package/dist/src/config/component/checkbox-input.model.d.ts +1 -0
  2. package/dist/src/config/component/checkbox-input.model.js +2 -1
  3. package/dist/src/config/component/checkbox-input.outline.d.ts +2 -1
  4. package/dist/src/config/component/checkbox-input.outline.js +1 -1
  5. package/dist/src/config/component/data-location.outline.d.ts +1 -0
  6. package/dist/src/config/component/file-upload.outline.d.ts +2 -0
  7. package/dist/src/config/component/file-upload.outline.js +1 -1
  8. package/dist/src/config/component/related-object-data.model.d.ts +45 -0
  9. package/dist/src/config/component/related-object-data.model.js +39 -0
  10. package/dist/src/config/component/related-object-data.outline.d.ts +59 -0
  11. package/dist/src/config/component/related-object-data.outline.js +5 -0
  12. package/dist/src/config/component/save-button.model.d.ts +1 -0
  13. package/dist/src/config/component/save-button.model.js +2 -1
  14. package/dist/src/config/component/save-button.outline.d.ts +5 -0
  15. package/dist/src/config/component/save-status.model.d.ts +4 -0
  16. package/dist/src/config/component/save-status.model.js +5 -1
  17. package/dist/src/config/component/save-status.outline.d.ts +20 -0
  18. package/dist/src/config/component/workspace.model.d.ts +44 -0
  19. package/dist/src/config/component/workspace.model.js +44 -0
  20. package/dist/src/config/component/workspace.outline.d.ts +62 -0
  21. package/dist/src/config/component/workspace.outline.js +5 -0
  22. package/dist/src/config/dictionary.model.d.ts +28 -4
  23. package/dist/src/config/dictionary.model.js +7 -1
  24. package/dist/src/config/dictionary.outline.d.ts +5 -3
  25. package/dist/src/config/form-behaviour.outline.d.ts +120 -7
  26. package/dist/src/config/form-behaviour.outline.js +13 -5
  27. package/dist/src/config/form-component.model.d.ts +1 -0
  28. package/dist/src/config/form-component.model.js +2 -1
  29. package/dist/src/config/form-component.outline.d.ts +14 -0
  30. package/dist/src/config/form-config.model.d.ts +3 -0
  31. package/dist/src/config/form-config.model.js +2 -1
  32. package/dist/src/config/form-config.outline.d.ts +10 -0
  33. package/dist/src/config/form-override.model.js +4 -3
  34. package/dist/src/config/visitor/base.model.d.ts +6 -0
  35. package/dist/src/config/visitor/base.model.js +13 -1
  36. package/dist/src/config/visitor/base.outline.d.ts +6 -0
  37. package/dist/src/config/visitor/common.model.js +2 -1
  38. package/dist/src/index.d.ts +9 -0
  39. package/dist/src/index.js +10 -1
  40. package/dist/src/internal/plain-record.d.ts +11 -0
  41. package/dist/src/internal/plain-record.js +21 -0
  42. package/dist/src/jsonata-helpers.d.ts +15 -0
  43. package/dist/src/jsonata-helpers.js +49 -13
  44. package/dist/src/jsonata-parity.fixtures.d.ts +9 -0
  45. package/dist/src/jsonata-parity.fixtures.js +25 -0
  46. package/dist/src/record-concurrency.model.d.ts +118 -0
  47. package/dist/src/record-concurrency.model.js +199 -0
  48. package/dist/src/record-diff.d.ts +69 -0
  49. package/dist/src/record-diff.js +298 -0
  50. package/dist/src/record-save.model.d.ts +154 -0
  51. package/dist/src/record-save.model.js +289 -0
  52. package/dist/src/testing.d.ts +3 -0
  53. package/dist/src/testing.js +20 -0
  54. package/dist/src/validation/record-validation.model.d.ts +84 -0
  55. package/dist/src/validation/record-validation.model.js +53 -0
  56. package/dist/src/validation/validation-groups.d.ts +29 -0
  57. package/dist/src/validation/validation-groups.fixtures.d.ts +20 -0
  58. package/dist/src/validation/validation-groups.fixtures.js +83 -0
  59. package/dist/src/validation/validation-groups.js +82 -0
  60. package/package.json +16 -11
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ /**
3
+ * Data-only optimistic-concurrency contracts shared by the server and browser.
4
+ * Runtime policy enforcement remains a backend responsibility.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isRecordConcurrencyRequestId = exports.RECORD_CONCURRENCY_REQUEST_ID_MAX_LENGTH = exports.RECORD_FORM_FINGERPRINT_PATTERN = exports.RECORD_FORM_FINGERPRINT_MAX_LENGTH = exports.RECORD_ENTITY_TAG_PATTERN = exports.RECORD_ENTITY_TAG_RECORD_ID_MAX_LENGTH = exports.RECORD_ENTITY_TAG_MAX_LENGTH = exports.RECORD_ENTITY_TAG_VERSION = exports.RECORD_REVISION_MAX = exports.RECORD_CONCURRENCY_PROBLEM_CODES = exports.RECORD_CONCURRENCY_RESOLUTIONS = exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_CONFIG = exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_MODE = exports.RECORD_CONCURRENT_MODIFICATION_MODES = void 0;
8
+ exports.isRecordConcurrentModificationMode = isRecordConcurrentModificationMode;
9
+ exports.validateRecordConcurrentModificationConfig = validateRecordConcurrentModificationConfig;
10
+ exports.isRecordConcurrentModificationConfig = isRecordConcurrentModificationConfig;
11
+ exports.resolveRecordConcurrentModificationConfig = resolveRecordConcurrentModificationConfig;
12
+ exports.resolveRecordConcurrentModificationMode = resolveRecordConcurrentModificationMode;
13
+ exports.coerceRecordConcurrentModificationConfig = coerceRecordConcurrentModificationConfig;
14
+ exports.isRecordConcurrencyResolution = isRecordConcurrencyResolution;
15
+ exports.isRecordConcurrencyProblemCode = isRecordConcurrencyProblemCode;
16
+ exports.isRecordRevision = isRecordRevision;
17
+ exports.recordEntityTagRevision = recordEntityTagRevision;
18
+ exports.isRecordEntityTag = isRecordEntityTag;
19
+ exports.isRecordFormFingerprint = isRecordFormFingerprint;
20
+ exports.isRecordConcurrencyMetadata = isRecordConcurrencyMetadata;
21
+ exports.sanitizeRecordConcurrencyMetadata = sanitizeRecordConcurrencyMetadata;
22
+ const plain_record_1 = require("./internal/plain-record");
23
+ const record_save_model_1 = require("./record-save.model");
24
+ exports.RECORD_CONCURRENT_MODIFICATION_MODES = ['last-write-wins', 'observe', 'strict'];
25
+ exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_MODE = 'last-write-wins';
26
+ exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_CONFIG = Object.freeze({
27
+ mode: exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_MODE,
28
+ });
29
+ exports.RECORD_CONCURRENCY_RESOLUTIONS = [
30
+ 'direct',
31
+ 'already-current',
32
+ 'client-auto-merged',
33
+ 'client-manually-resolved',
34
+ 'internal',
35
+ ];
36
+ exports.RECORD_CONCURRENCY_PROBLEM_CODES = [
37
+ 'record-precondition-required',
38
+ 'record-revision-stale',
39
+ 'record-deleted',
40
+ 'record-concurrency-capability-unavailable',
41
+ 'form-definition-changed',
42
+ 'record-lifecycle-operation-conflict',
43
+ ];
44
+ /** Revisions are exact non-negative integers, not timestamps or floating-point counters. */
45
+ exports.RECORD_REVISION_MAX = Number.MAX_SAFE_INTEGER;
46
+ /**
47
+ * Entity tags are quoted, bounded, opaque values produced by one backend
48
+ * helper. Clients retain and return the complete value; they never construct a
49
+ * tag from the numeric revision.
50
+ */
51
+ exports.RECORD_ENTITY_TAG_VERSION = 'rb-record-v1';
52
+ exports.RECORD_ENTITY_TAG_MAX_LENGTH = 128;
53
+ exports.RECORD_ENTITY_TAG_RECORD_ID_MAX_LENGTH = 1_024;
54
+ /** Base64url SHA-256 digest length, without padding. */
55
+ const RECORD_ENTITY_TAG_DIGEST_LENGTH = 43;
56
+ /**
57
+ * `"<version>.<revision>.<digest>"`. Built from the version constant so a
58
+ * future format bump cannot leave the guard matching the previous shape.
59
+ */
60
+ exports.RECORD_ENTITY_TAG_PATTERN = new RegExp(`^"${exports.RECORD_ENTITY_TAG_VERSION}\\.(0|[1-9][0-9]{0,15})\\.[A-Za-z0-9_-]{${RECORD_ENTITY_TAG_DIGEST_LENGTH}}"$`);
61
+ /**
62
+ * Form fingerprints are deliberately independent of record revisions and
63
+ * entity tags: an administrator editing a form must not invalidate API
64
+ * operations that never rendered it.
65
+ */
66
+ exports.RECORD_FORM_FINGERPRINT_MAX_LENGTH = 128;
67
+ exports.RECORD_FORM_FINGERPRINT_PATTERN = record_save_model_1.RECORD_SAVE_PUBLIC_IDENTIFIER_PATTERN;
68
+ function isRecordConcurrentModificationMode(value) {
69
+ return typeof value === 'string' && exports.RECORD_CONCURRENT_MODIFICATION_MODES.includes(value);
70
+ }
71
+ /**
72
+ * Validate absent, valid, and malformed record-type policy. Absent policy is
73
+ * the compatibility default; an explicit but malformed policy is reported so
74
+ * enforcement boundaries can fail closed rather than silently defaulting.
75
+ * No raw input is retained in the result.
76
+ */
77
+ function validateRecordConcurrentModificationConfig(value) {
78
+ if (value === undefined || value === null) {
79
+ return {
80
+ valid: true,
81
+ config: { ...exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_CONFIG },
82
+ defaulted: true,
83
+ };
84
+ }
85
+ if (!(0, plain_record_1.isPlainRecord)(value)) {
86
+ return { valid: false, reason: 'malformed-config' };
87
+ }
88
+ if (!isRecordConcurrentModificationMode(value.mode)) {
89
+ return { valid: false, reason: 'malformed-mode' };
90
+ }
91
+ return { valid: true, config: { mode: value.mode }, defaulted: false };
92
+ }
93
+ /** True only for an explicit, well-formed policy object. */
94
+ function isRecordConcurrentModificationConfig(value) {
95
+ const validation = validateRecordConcurrentModificationConfig(value);
96
+ return validation.valid && !validation.defaulted;
97
+ }
98
+ /**
99
+ * Resolve the compatibility default while failing closed for explicit
100
+ * malformed policy. Use this at enforcement boundaries, where guessing a mode
101
+ * would risk permitting an unguarded write.
102
+ */
103
+ function resolveRecordConcurrentModificationConfig(value) {
104
+ const validation = validateRecordConcurrentModificationConfig(value);
105
+ if (!validation.valid) {
106
+ throw new TypeError(`Record concurrent-modification configuration is ${validation.reason}.`);
107
+ }
108
+ return validation.config;
109
+ }
110
+ function resolveRecordConcurrentModificationMode(value) {
111
+ return resolveRecordConcurrentModificationConfig(value).mode;
112
+ }
113
+ /**
114
+ * Non-throwing counterpart for presentation boundaries such as record-type
115
+ * discovery, where one corrupted stored policy must not break an unrelated
116
+ * listing. Reporting the default is safe because it cannot loosen enforcement:
117
+ * a malformed policy still fails closed when a mutation resolves it.
118
+ */
119
+ function coerceRecordConcurrentModificationConfig(value) {
120
+ const validation = validateRecordConcurrentModificationConfig(value);
121
+ return validation.valid ? validation.config : { ...exports.DEFAULT_RECORD_CONCURRENT_MODIFICATION_CONFIG };
122
+ }
123
+ function isRecordConcurrencyResolution(value) {
124
+ return typeof value === 'string' && exports.RECORD_CONCURRENCY_RESOLUTIONS.includes(value);
125
+ }
126
+ function isRecordConcurrencyProblemCode(value) {
127
+ return typeof value === 'string' && exports.RECORD_CONCURRENCY_PROBLEM_CODES.includes(value);
128
+ }
129
+ function isRecordRevision(value) {
130
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 && value <= exports.RECORD_REVISION_MAX;
131
+ }
132
+ function recordEntityTagRevision(value) {
133
+ if (typeof value !== 'string' || value.length > exports.RECORD_ENTITY_TAG_MAX_LENGTH)
134
+ return undefined;
135
+ const match = exports.RECORD_ENTITY_TAG_PATTERN.exec(value);
136
+ const revision = match ? Number(match[1]) : undefined;
137
+ return isRecordRevision(revision) ? revision : undefined;
138
+ }
139
+ /**
140
+ * Structural entity-tag guard. Record identity is certified by the backend
141
+ * parser, which recomputes the digest for a known OID; this guard only proves
142
+ * the value has the bounded opaque shape worth carrying in client state.
143
+ */
144
+ function isRecordEntityTag(value) {
145
+ return recordEntityTagRevision(value) !== undefined;
146
+ }
147
+ function isRecordFormFingerprint(value) {
148
+ return (typeof value === 'string' &&
149
+ value.length > 0 &&
150
+ value.length <= exports.RECORD_FORM_FINGERPRINT_MAX_LENGTH &&
151
+ exports.RECORD_FORM_FINGERPRINT_PATTERN.test(value));
152
+ }
153
+ exports.RECORD_CONCURRENCY_REQUEST_ID_MAX_LENGTH = record_save_model_1.RECORD_SAVE_REQUEST_ID_MAX_LENGTH;
154
+ /** Diagnostic request linkage uses the same canonical save request-id format. */
155
+ exports.isRecordConcurrencyRequestId = record_save_model_1.isRecordSaveRequestId;
156
+ /** Runtime guard used at transport boundaries for bounded concurrency metadata. */
157
+ function isRecordConcurrencyMetadata(value) {
158
+ if (!(0, plain_record_1.isPlainRecord)(value)) {
159
+ return false;
160
+ }
161
+ return ((value.mode === undefined || isRecordConcurrentModificationMode(value.mode)) &&
162
+ (value.revision === undefined || isRecordRevision(value.revision)) &&
163
+ (value.expectedRevision === undefined || isRecordRevision(value.expectedRevision)) &&
164
+ (value.currentRevision === undefined || isRecordRevision(value.currentRevision)) &&
165
+ (value.entityTag === undefined || isRecordEntityTag(value.entityTag)) &&
166
+ (value.formFingerprint === undefined || isRecordFormFingerprint(value.formFingerprint)) &&
167
+ (value.resolution === undefined || isRecordConcurrencyResolution(value.resolution)) &&
168
+ (value.resolutionOfRequestId === undefined || (0, exports.isRecordConcurrencyRequestId)(value.resolutionOfRequestId)));
169
+ }
170
+ /**
171
+ * Copy only valid bounded fields from untrusted or cross-runtime metadata.
172
+ * Unknown keys are dropped rather than carried, so a payload cannot widen the
173
+ * diagnostic contract. Returns `undefined` when nothing survives.
174
+ */
175
+ function sanitizeRecordConcurrencyMetadata(value) {
176
+ if (!(0, plain_record_1.isPlainRecord)(value)) {
177
+ return undefined;
178
+ }
179
+ const result = {};
180
+ if (isRecordConcurrentModificationMode(value.mode))
181
+ result.mode = value.mode;
182
+ if (isRecordRevision(value.revision))
183
+ result.revision = value.revision;
184
+ if (isRecordRevision(value.expectedRevision))
185
+ result.expectedRevision = value.expectedRevision;
186
+ if (isRecordRevision(value.currentRevision))
187
+ result.currentRevision = value.currentRevision;
188
+ if (isRecordEntityTag(value.entityTag))
189
+ result.entityTag = value.entityTag;
190
+ if (isRecordFormFingerprint(value.formFingerprint))
191
+ result.formFingerprint = value.formFingerprint;
192
+ if (isRecordConcurrencyResolution(value.resolution))
193
+ result.resolution = value.resolution;
194
+ if ((0, exports.isRecordConcurrencyRequestId)(value.resolutionOfRequestId)) {
195
+ result.resolutionOfRequestId = value.resolutionOfRequestId;
196
+ }
197
+ return Object.keys(result).length > 0 ? result : undefined;
198
+ }
199
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLWNvbmN1cnJlbmN5Lm1vZGVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlY29yZC1jb25jdXJyZW5jeS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHOzs7QUE4R0gsZ0ZBRUM7QUFRRCxnR0FpQkM7QUFHRCxvRkFHQztBQU9ELDhGQU1DO0FBRUQsMEZBRUM7QUFRRCw0RkFHQztBQUVELHNFQUVDO0FBRUQsd0VBRUM7QUFFRCw0Q0FFQztBQUVELDBEQUtDO0FBT0QsOENBRUM7QUFFRCwwREFPQztBQVFELGtFQWNDO0FBT0QsOEVBZ0JDO0FBM1BELDBEQUF3RDtBQUN4RCwyREFJNkI7QUFFaEIsUUFBQSxvQ0FBb0MsR0FBRyxDQUFDLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxRQUFRLENBQVUsQ0FBQztBQVF6RixRQUFBLDJDQUEyQyxHQUFHLGlCQUEwQixDQUFDO0FBQ3pFLFFBQUEsNkNBQTZDLEdBQ3hELE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDWixJQUFJLEVBQUUsbURBQTJDO0NBQ2xELENBQUMsQ0FBQztBQWFRLFFBQUEsOEJBQThCLEdBQUc7SUFDNUMsUUFBUTtJQUNSLGlCQUFpQjtJQUNqQixvQkFBb0I7SUFDcEIsMEJBQTBCO0lBQzFCLFVBQVU7Q0FDRixDQUFDO0FBU0UsUUFBQSxnQ0FBZ0MsR0FBRztJQUM5Qyw4QkFBOEI7SUFDOUIsdUJBQXVCO0lBQ3ZCLGdCQUFnQjtJQUNoQiwyQ0FBMkM7SUFDM0MseUJBQXlCO0lBQ3pCLHFDQUFxQztDQUM3QixDQUFDO0FBSVgsNEZBQTRGO0FBQy9FLFFBQUEsbUJBQW1CLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDO0FBRTNEOzs7O0dBSUc7QUFDVSxRQUFBLHlCQUF5QixHQUFHLGNBQXVCLENBQUM7QUFDcEQsUUFBQSw0QkFBNEIsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBQSxzQ0FBc0MsR0FBRyxLQUFLLENBQUM7QUFFNUQs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
@@ -0,0 +1,69 @@
1
+ /** A property or array-index path through a JSON-like record value. */
2
+ export type RecordValuePath = Array<string | number>;
3
+ export type RecordValueChangeKind = 'add' | 'delete' | 'change';
4
+ /**
5
+ * One structural change between two JSON-like values.
6
+ *
7
+ * Object additions/deletions and array-index additions/deletions retain their
8
+ * historical backend semantics. Concurrency callers should use
9
+ * `diffRecordValuesForConcurrency`, which treats an array as one atomic value.
10
+ */
11
+ export interface RecordValueChange {
12
+ readonly kind: RecordValueChangeKind;
13
+ readonly path: RecordValuePath;
14
+ readonly original: unknown;
15
+ readonly changed: unknown;
16
+ }
17
+ export interface RecordValueOverlap {
18
+ readonly path: RecordValuePath;
19
+ readonly local: RecordValueChange;
20
+ readonly remote: RecordValueChange;
21
+ readonly resolved: boolean;
22
+ }
23
+ export interface ThreeWayRecordDiff {
24
+ readonly localChanges: readonly RecordValueChange[];
25
+ readonly remoteChanges: readonly RecordValueChange[];
26
+ readonly applicableLocalChanges: readonly RecordValueChange[];
27
+ readonly resolvedOverlaps: readonly RecordValueOverlap[];
28
+ readonly unresolvedOverlaps: readonly RecordValueOverlap[];
29
+ /** True when latest already contains every base-to-local final value. */
30
+ readonly localChangesAlreadyPresent: boolean;
31
+ }
32
+ export interface ThreeWayRecordRebase<T> extends ThreeWayRecordDiff {
33
+ /** Latest plus only base-to-local changes that do not diverge from remote. */
34
+ readonly candidate: T;
35
+ }
36
+ /**
37
+ * Pure recursive diff retaining the established FormRecordConsistencyService
38
+ * add/delete/change and path ordering contract.
39
+ */
40
+ export declare function diffRecordValues(original: unknown, changed: unknown, path?: readonly (string | number)[]): RecordValueChange[];
41
+ /**
42
+ * Collapse a descendant of an array to the containing array path. Numeric path
43
+ * segments are emitted only by array traversal; numeric-looking object keys
44
+ * remain strings and therefore remain ordinary object properties.
45
+ */
46
+ export declare function normalizeConcurrencyPath(path: readonly (string | number)[]): RecordValuePath;
47
+ /** Prefix-aware path overlap: equality, local parent, or remote parent. */
48
+ export declare function recordValuePathsOverlap(first: readonly (string | number)[], second: readonly (string | number)[]): boolean;
49
+ /** Deterministic deep equality for JSON-like values; object key order is ignored. */
50
+ export declare function canonicallyEqualRecordValues(first: unknown, second: unknown): boolean;
51
+ /**
52
+ * Concurrency diff with arrays/repeatables represented by one whole-value
53
+ * change at their root. The ordinary diff remains index-based for audit users.
54
+ */
55
+ export declare function diffRecordValuesForConcurrency(original: unknown, changed: unknown, path?: readonly (string | number)[]): RecordValueChange[];
56
+ /**
57
+ * Compare base/local/latest and classify overlaps using final projected state,
58
+ * not merely the leaf values stored on individual diff entries.
59
+ */
60
+ export declare function compareThreeWayRecordValues(base: unknown, local: unknown, latest: unknown): ThreeWayRecordDiff;
61
+ /**
62
+ * Clone latest and apply the supplied structural changes without mutating any
63
+ * snapshot. Numeric deletes against the same array are applied from the
64
+ * highest index down, so a compatible `diffRecordValues()` result cannot
65
+ * shift a later delete onto the wrong item.
66
+ */
67
+ export declare function applyRecordValueChanges<T>(latest: T, changes: readonly RecordValueChange[]): T;
68
+ /** Build latest-plus-local while retaining divergent overlaps for later review. */
69
+ export declare function rebaseRecordValues<T>(base: unknown, local: unknown, latest: T): ThreeWayRecordRebase<T>;
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.diffRecordValues = diffRecordValues;
4
+ exports.normalizeConcurrencyPath = normalizeConcurrencyPath;
5
+ exports.recordValuePathsOverlap = recordValuePathsOverlap;
6
+ exports.canonicallyEqualRecordValues = canonicallyEqualRecordValues;
7
+ exports.diffRecordValuesForConcurrency = diffRecordValuesForConcurrency;
8
+ exports.compareThreeWayRecordValues = compareThreeWayRecordValues;
9
+ exports.applyRecordValueChanges = applyRecordValueChanges;
10
+ exports.rebaseRecordValues = rebaseRecordValues;
11
+ const lodash_1 = require("lodash");
12
+ const plain_record_1 = require("./internal/plain-record");
13
+ /**
14
+ * Pure recursive diff retaining the established FormRecordConsistencyService
15
+ * add/delete/change and path ordering contract.
16
+ */
17
+ function diffRecordValues(original, changed, path = []) {
18
+ if (original === changed)
19
+ return [];
20
+ const originalArray = Array.isArray(original);
21
+ const changedArray = Array.isArray(changed);
22
+ const originalRecord = (0, plain_record_1.isPlainRecord)(original);
23
+ const changedRecord = (0, plain_record_1.isPlainRecord)(changed);
24
+ if ((originalArray && changedArray) || (originalRecord && changedRecord)) {
25
+ const originalKeys = valueKeys(original);
26
+ const changedKeys = valueKeys(changed);
27
+ const originalKeySet = new Set(originalKeys);
28
+ const changedKeySet = new Set(changedKeys);
29
+ const result = [];
30
+ for (const key of originalKeys) {
31
+ const nextPath = [...path, key];
32
+ const originalValue = valueAtKey(original, key);
33
+ if (!changedKeySet.has(key)) {
34
+ result.push({ kind: 'delete', path: nextPath, original: originalValue, changed: undefined });
35
+ continue;
36
+ }
37
+ result.push(...diffRecordValues(originalValue, valueAtKey(changed, key), nextPath));
38
+ }
39
+ for (const key of changedKeys) {
40
+ if (originalKeySet.has(key))
41
+ continue;
42
+ result.push({
43
+ kind: 'add',
44
+ path: [...path, key],
45
+ original: undefined,
46
+ changed: valueAtKey(changed, key),
47
+ });
48
+ }
49
+ return result;
50
+ }
51
+ return [{ kind: 'change', path: [...path], original, changed }];
52
+ }
53
+ /**
54
+ * Collapse a descendant of an array to the containing array path. Numeric path
55
+ * segments are emitted only by array traversal; numeric-looking object keys
56
+ * remain strings and therefore remain ordinary object properties.
57
+ */
58
+ function normalizeConcurrencyPath(path) {
59
+ const firstArrayIndex = path.findIndex(segment => typeof segment === 'number');
60
+ return firstArrayIndex < 0 ? [...path] : path.slice(0, firstArrayIndex);
61
+ }
62
+ /** Prefix-aware path overlap: equality, local parent, or remote parent. */
63
+ function recordValuePathsOverlap(first, second) {
64
+ const commonLength = Math.min(first.length, second.length);
65
+ for (let index = 0; index < commonLength; index += 1) {
66
+ if (first[index] !== second[index])
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ /** Deterministic deep equality for JSON-like values; object key order is ignored. */
72
+ function canonicallyEqualRecordValues(first, second) {
73
+ return (0, lodash_1.isEqual)(first, second);
74
+ }
75
+ /**
76
+ * Concurrency diff with arrays/repeatables represented by one whole-value
77
+ * change at their root. The ordinary diff remains index-based for audit users.
78
+ */
79
+ function diffRecordValuesForConcurrency(original, changed, path = []) {
80
+ if (canonicallyEqualRecordValues(original, changed))
81
+ return [];
82
+ if (Array.isArray(original) || Array.isArray(changed)) {
83
+ return [{ kind: 'change', path: [...path], original, changed }];
84
+ }
85
+ const originalRecord = (0, plain_record_1.isPlainRecord)(original);
86
+ const changedRecord = (0, plain_record_1.isPlainRecord)(changed);
87
+ if (originalRecord && changedRecord) {
88
+ const result = [];
89
+ const changedKeys = new Set(Object.keys(changed));
90
+ const originalKeys = Object.keys(original);
91
+ const originalKeySet = new Set(originalKeys);
92
+ for (const key of originalKeys) {
93
+ const nextPath = [...path, key];
94
+ if (!changedKeys.has(key)) {
95
+ result.push({ kind: 'delete', path: nextPath, original: original[key], changed: undefined });
96
+ continue;
97
+ }
98
+ result.push(...diffRecordValuesForConcurrency(original[key], changed[key], nextPath));
99
+ }
100
+ for (const key of Object.keys(changed)) {
101
+ if (originalKeySet.has(key))
102
+ continue;
103
+ result.push({ kind: 'add', path: [...path, key], original: undefined, changed: changed[key] });
104
+ }
105
+ return result;
106
+ }
107
+ return [{ kind: 'change', path: [...path], original, changed }];
108
+ }
109
+ /**
110
+ * Compare base/local/latest and classify overlaps using final projected state,
111
+ * not merely the leaf values stored on individual diff entries.
112
+ */
113
+ function compareThreeWayRecordValues(base, local, latest) {
114
+ const localChanges = diffRecordValuesForConcurrency(base, local);
115
+ const remoteChanges = diffRecordValuesForConcurrency(base, latest);
116
+ const resolvedOverlaps = [];
117
+ const unresolvedOverlaps = [];
118
+ const localWithDivergentOverlap = new Set();
119
+ for (const localChange of localChanges) {
120
+ for (const remoteChange of remoteChanges) {
121
+ if (!recordValuePathsOverlap(localChange.path, remoteChange.path))
122
+ continue;
123
+ const overlapPath = localChange.path.length <= remoteChange.path.length ? localChange.path : remoteChange.path;
124
+ const resolved = locatedValuesEqual(valueAtPath(local, overlapPath), valueAtPath(latest, overlapPath));
125
+ const overlap = {
126
+ path: [...overlapPath],
127
+ local: localChange,
128
+ remote: remoteChange,
129
+ resolved,
130
+ };
131
+ if (resolved) {
132
+ resolvedOverlaps.push(overlap);
133
+ }
134
+ else {
135
+ unresolvedOverlaps.push(overlap);
136
+ localWithDivergentOverlap.add(localChange);
137
+ }
138
+ }
139
+ }
140
+ const applicableLocalChanges = localChanges.filter(change => {
141
+ if (localWithDivergentOverlap.has(change))
142
+ return false;
143
+ return !remoteChanges.some(remote => recordValuePathsOverlap(change.path, remote.path));
144
+ });
145
+ const localChangesAlreadyPresent = localChanges.every(change => locatedValuesEqual(valueAtPath(local, change.path), valueAtPath(latest, change.path)));
146
+ return {
147
+ localChanges,
148
+ remoteChanges,
149
+ applicableLocalChanges,
150
+ resolvedOverlaps,
151
+ unresolvedOverlaps,
152
+ localChangesAlreadyPresent,
153
+ };
154
+ }
155
+ /**
156
+ * Clone latest and apply the supplied structural changes without mutating any
157
+ * snapshot. Numeric deletes against the same array are applied from the
158
+ * highest index down, so a compatible `diffRecordValues()` result cannot
159
+ * shift a later delete onto the wrong item.
160
+ */
161
+ function applyRecordValueChanges(latest, changes) {
162
+ let result = (0, lodash_1.cloneDeep)(latest);
163
+ for (const change of changesInApplicationOrder(changes)) {
164
+ if (change.path.length === 0) {
165
+ result = change.kind === 'delete' ? undefined : (0, lodash_1.cloneDeep)(change.changed);
166
+ continue;
167
+ }
168
+ result = applyChangeAtPath(result, change);
169
+ }
170
+ return result;
171
+ }
172
+ function changesInApplicationOrder(changes) {
173
+ const arrayDeleteGroups = new Map();
174
+ for (const change of changes) {
175
+ const key = arrayDeleteParentKey(change);
176
+ if (key === undefined)
177
+ continue;
178
+ const group = arrayDeleteGroups.get(key) ?? [];
179
+ group.push(change);
180
+ arrayDeleteGroups.set(key, group);
181
+ }
182
+ for (const group of arrayDeleteGroups.values()) {
183
+ group.sort((first, second) => {
184
+ const firstIndex = first.path[first.path.length - 1];
185
+ const secondIndex = second.path[second.path.length - 1];
186
+ return secondIndex - firstIndex;
187
+ });
188
+ for (let index = 1; index < group.length; index += 1) {
189
+ const previousIndex = group[index - 1].path[group[index - 1].path.length - 1];
190
+ const currentIndex = group[index].path[group[index].path.length - 1];
191
+ if (previousIndex === currentIndex) {
192
+ throw new TypeError('A record change set cannot delete the same array index more than once.');
193
+ }
194
+ }
195
+ }
196
+ const emittedGroups = new Set();
197
+ const ordered = [];
198
+ for (const change of changes) {
199
+ const key = arrayDeleteParentKey(change);
200
+ if (key === undefined) {
201
+ ordered.push(change);
202
+ continue;
203
+ }
204
+ if (emittedGroups.has(key))
205
+ continue;
206
+ emittedGroups.add(key);
207
+ ordered.push(...(arrayDeleteGroups.get(key) ?? []));
208
+ }
209
+ return ordered;
210
+ }
211
+ function arrayDeleteParentKey(change) {
212
+ if (change.kind !== 'delete' || change.path.length === 0)
213
+ return undefined;
214
+ const finalSegment = change.path[change.path.length - 1];
215
+ if (typeof finalSegment !== 'number')
216
+ return undefined;
217
+ if (!Number.isSafeInteger(finalSegment) || finalSegment < 0) {
218
+ throw new TypeError('A record change array index must be a non-negative safe integer.');
219
+ }
220
+ return JSON.stringify(change.path.slice(0, -1));
221
+ }
222
+ /** Build latest-plus-local while retaining divergent overlaps for later review. */
223
+ function rebaseRecordValues(base, local, latest) {
224
+ const comparison = compareThreeWayRecordValues(base, local, latest);
225
+ return {
226
+ ...comparison,
227
+ candidate: applyRecordValueChanges(latest, comparison.applicableLocalChanges),
228
+ };
229
+ }
230
+ function valueKeys(value) {
231
+ if (Array.isArray(value))
232
+ return Array.from({ length: value.length }, (_, index) => index);
233
+ return (0, plain_record_1.isPlainRecord)(value) ? Object.keys(value) : [];
234
+ }
235
+ function valueAtKey(value, key) {
236
+ return value[key];
237
+ }
238
+ function valueAtPath(value, path) {
239
+ let current = value;
240
+ if (path.length === 0)
241
+ return { exists: true, value: current };
242
+ for (const segment of path) {
243
+ if ((!Array.isArray(current) && !(0, plain_record_1.isPlainRecord)(current)) || !hasOwn(current, segment)) {
244
+ return { exists: false, value: undefined };
245
+ }
246
+ current = current[segment];
247
+ }
248
+ return { exists: true, value: current };
249
+ }
250
+ function locatedValuesEqual(first, second) {
251
+ return first.exists === second.exists && (!first.exists || canonicallyEqualRecordValues(first.value, second.value));
252
+ }
253
+ function applyChangeAtPath(root, change) {
254
+ const clonedRoot = isContainer(root) ? root : containerFor(change.path[0]);
255
+ let parent = clonedRoot;
256
+ for (let index = 0; index < change.path.length - 1; index += 1) {
257
+ const segment = change.path[index];
258
+ const nextSegment = change.path[index + 1];
259
+ // Never traverse an inherited container. In particular, `__proto__` on a
260
+ // normal object resolves to Object.prototype; reusing it would let an
261
+ // otherwise ordinary record change mutate the global prototype.
262
+ const existing = hasOwn(parent, segment) ? parent[segment] : undefined;
263
+ const next = isContainer(existing) ? existing : containerFor(nextSegment);
264
+ defineValue(parent, segment, next);
265
+ parent = next;
266
+ }
267
+ const finalSegment = change.path[change.path.length - 1];
268
+ if (change.kind === 'delete') {
269
+ if (Array.isArray(parent) && typeof finalSegment === 'number') {
270
+ parent.splice(finalSegment, 1);
271
+ }
272
+ else {
273
+ delete parent[finalSegment];
274
+ }
275
+ }
276
+ else {
277
+ defineValue(parent, finalSegment, (0, lodash_1.cloneDeep)(change.changed));
278
+ }
279
+ return clonedRoot;
280
+ }
281
+ function defineValue(target, key, value) {
282
+ Object.defineProperty(target, key, {
283
+ configurable: true,
284
+ enumerable: true,
285
+ writable: true,
286
+ value,
287
+ });
288
+ }
289
+ function containerFor(segment) {
290
+ return typeof segment === 'number' ? [] : {};
291
+ }
292
+ function isContainer(value) {
293
+ return Array.isArray(value) || (0, plain_record_1.isPlainRecord)(value);
294
+ }
295
+ function hasOwn(value, key) {
296
+ return Object.prototype.hasOwnProperty.call(value, key);
297
+ }
298
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLWRpZmYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVjb3JkLWRpZmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFxREEsNENBMENDO0FBT0QsNERBR0M7QUFHRCwwREFTQztBQUdELG9FQUVDO0FBTUQsd0VBa0NDO0FBTUQsa0VBMkNDO0FBUUQsMERBVUM7QUFvREQsZ0RBTUM7QUEvUkQsbUNBQXNFO0FBQ3RFLDBEQUF3RDtBQWdEeEQ7OztHQUdHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQzlCLFFBQWlCLEVBQ2pCLE9BQWdCLEVBQ2hCLE9BQXFDLEVBQUU7SUFFdkMsSUFBSSxRQUFRLEtBQUssT0FBTztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBRXBDLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM1QyxNQUFNLGNBQWMsR0FBRyxJQUFBLDRCQUFhLEVBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0MsTUFBTSxhQUFhLEdBQUcsSUFBQSw0QkFBYSxFQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRTdDLElBQUksQ0FBQyxhQUFhLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksYUFBYSxDQUFDLEVBQUUsQ0FBQztRQUN6RSxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekMsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxDQUFrQixZQUFZLENBQUMsQ0FBQztRQUM5RCxNQUFNLGFBQWEsR0FBRyxJQUFJLEdBQUcsQ0FBa0IsV0FBVyxDQUFDLENBQUM7UUFDNUQsTUFBTSxNQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUV2QyxLQUFLLE1BQU0sR0FBRyxJQUFJ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