@memberjunction/integration-engine 5.40.2 → 5.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +34 -0
  2. package/dist/BaseIntegrationConnector.d.ts +109 -0
  3. package/dist/BaseIntegrationConnector.d.ts.map +1 -1
  4. package/dist/BaseIntegrationConnector.js +308 -93
  5. package/dist/BaseIntegrationConnector.js.map +1 -1
  6. package/dist/BaseRESTIntegrationConnector.d.ts +32 -0
  7. package/dist/BaseRESTIntegrationConnector.d.ts.map +1 -1
  8. package/dist/BaseRESTIntegrationConnector.js +182 -28
  9. package/dist/BaseRESTIntegrationConnector.js.map +1 -1
  10. package/dist/ContentHash.d.ts +22 -0
  11. package/dist/ContentHash.d.ts.map +1 -1
  12. package/dist/ContentHash.js +35 -0
  13. package/dist/ContentHash.js.map +1 -1
  14. package/dist/CustomColumnPromotion.d.ts +108 -0
  15. package/dist/CustomColumnPromotion.d.ts.map +1 -0
  16. package/dist/CustomColumnPromotion.js +202 -0
  17. package/dist/CustomColumnPromotion.js.map +1 -0
  18. package/dist/CustomOverflow.d.ts +64 -0
  19. package/dist/CustomOverflow.d.ts.map +1 -0
  20. package/dist/CustomOverflow.js +74 -0
  21. package/dist/CustomOverflow.js.map +1 -0
  22. package/dist/FieldMappingEngine.d.ts.map +1 -1
  23. package/dist/FieldMappingEngine.js +22 -3
  24. package/dist/FieldMappingEngine.js.map +1 -1
  25. package/dist/IntegrationConnectorCreationPipeline.d.ts +33 -0
  26. package/dist/IntegrationConnectorCreationPipeline.d.ts.map +1 -1
  27. package/dist/IntegrationConnectorCreationPipeline.js +157 -0
  28. package/dist/IntegrationConnectorCreationPipeline.js.map +1 -1
  29. package/dist/IntegrationEngine.d.ts +106 -6
  30. package/dist/IntegrationEngine.d.ts.map +1 -1
  31. package/dist/IntegrationEngine.js +874 -170
  32. package/dist/IntegrationEngine.js.map +1 -1
  33. package/dist/IntegrationSchemaSync.d.ts +84 -13
  34. package/dist/IntegrationSchemaSync.d.ts.map +1 -1
  35. package/dist/IntegrationSchemaSync.js +198 -36
  36. package/dist/IntegrationSchemaSync.js.map +1 -1
  37. package/dist/KeySerialization.d.ts +21 -0
  38. package/dist/KeySerialization.d.ts.map +1 -0
  39. package/dist/KeySerialization.js +29 -0
  40. package/dist/KeySerialization.js.map +1 -0
  41. package/dist/MatchEngine.d.ts.map +1 -1
  42. package/dist/MatchEngine.js +12 -4
  43. package/dist/MatchEngine.js.map +1 -1
  44. package/dist/RecordFlatten.d.ts +49 -0
  45. package/dist/RecordFlatten.d.ts.map +1 -0
  46. package/dist/RecordFlatten.js +50 -0
  47. package/dist/RecordFlatten.js.map +1 -0
  48. package/dist/StreamingDiscovery.d.ts +145 -0
  49. package/dist/StreamingDiscovery.d.ts.map +1 -0
  50. package/dist/StreamingDiscovery.js +306 -0
  51. package/dist/StreamingDiscovery.js.map +1 -0
  52. package/dist/SyncLogger.d.ts +1 -1
  53. package/dist/SyncLogger.d.ts.map +1 -1
  54. package/dist/SyncLogger.js +19 -1
  55. package/dist/SyncLogger.js.map +1 -1
  56. package/dist/auth-helpers/BasicAuthHeaderBuilder.d.ts +36 -0
  57. package/dist/auth-helpers/BasicAuthHeaderBuilder.d.ts.map +1 -0
  58. package/dist/auth-helpers/BasicAuthHeaderBuilder.js +38 -0
  59. package/dist/auth-helpers/BasicAuthHeaderBuilder.js.map +1 -0
  60. package/dist/auth-helpers/OAuth1aSigner.d.ts +56 -0
  61. package/dist/auth-helpers/OAuth1aSigner.d.ts.map +1 -0
  62. package/dist/auth-helpers/OAuth1aSigner.js +91 -0
  63. package/dist/auth-helpers/OAuth1aSigner.js.map +1 -0
  64. package/dist/auth-helpers/OAuth2TokenManager.d.ts +103 -0
  65. package/dist/auth-helpers/OAuth2TokenManager.d.ts.map +1 -0
  66. package/dist/auth-helpers/OAuth2TokenManager.js +143 -0
  67. package/dist/auth-helpers/OAuth2TokenManager.js.map +1 -0
  68. package/dist/auth-helpers/index.d.ts +11 -0
  69. package/dist/auth-helpers/index.d.ts.map +1 -0
  70. package/dist/auth-helpers/index.js +8 -0
  71. package/dist/auth-helpers/index.js.map +1 -0
  72. package/dist/index.d.ts +15 -1
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +9 -0
  75. package/dist/index.js.map +1 -1
  76. package/dist/types.d.ts +73 -0
  77. package/dist/types.d.ts.map +1 -1
  78. package/package.json +7 -7
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Key-value serialization for record identity.
3
+ *
4
+ * `serializeKeyValue` mirrors the engine's write-side value coercion (see
5
+ * `IntegrationEngine` value-handling: object/array → `JSON.stringify`, NOT the JS default
6
+ * `"[object Object]"`). It is used to build a record's composite ExternalID / load key from
7
+ * its primary-key field VALUES, so the key derived at load time equals the value persisted in
8
+ * the column for object-valued PKs — without this, every object-valued PK would collapse to
9
+ * `"[object Object]"` and all such records would share one identity (the duplicate-row class
10
+ * of bug).
11
+ *
12
+ * Contract (pinned by call sites in `BaseRESTIntegrationConnector`, `MatchEngine`,
13
+ * `IntegrationEngine.extractMappedPrimaryKey`):
14
+ * - `null` / `undefined` → `''` (empty string). Callers treat `''` as a missing key component
15
+ * (`if (s === '') return null` / `serializeKeyValue(v).length > 0`), which routes genuinely
16
+ * keyless / partial-key rows to the content-hash identity fallback rather than a bogus key.
17
+ * - plain object / array (anything `typeof === 'object'` that is not a `Date`) → `JSON.stringify`.
18
+ * - everything else (string / number / boolean / Date / bigint / symbol) → `String(value)`.
19
+ */
20
+ export function serializeKeyValue(value) {
21
+ if (value == null) {
22
+ return '';
23
+ }
24
+ if (typeof value === 'object' && !(value instanceof Date)) {
25
+ return JSON.stringify(value);
26
+ }
27
+ return String(value);
28
+ }
29
+ //# sourceMappingURL=KeySerialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeySerialization.js","sourceRoot":"","sources":["../src/KeySerialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC5C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MatchEngine.d.ts","sourceRoot":"","sources":["../src/MatchEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAqB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAEnE;;;GAGG;AACH,qBAAa,WAAW;IACpB,gFAAgF;IAChF,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEtC,4FAA4F;IAC5F,SAAS,KAAK,aAAa,IAAI,iBAAiB,CAE/C;IAED;;;;;;;;;OASG;IACU,OAAO,CAChB,OAAO,EAAE,YAAY,EAAE,EACvB,SAAS,EAAE,4BAA4B,EACvC,SAAS,EAAE,2BAA2B,EAAE,EACxC,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC;IAmB1B;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;YACW,oBAAoB;IAmBlC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;;;;;;;OAQG;YACW,kBAAkB;IAuBhC;;;;;;;;;OASG;YACW,eAAe;IAiD7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAc3B;;OAEG;YACW,kBAAkB;CA0BnC"}
1
+ {"version":3,"file":"MatchEngine.d.ts","sourceRoot":"","sources":["../src/MatchEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAqB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAGnE;;;GAGG;AACH,qBAAa,WAAW;IACpB,gFAAgF;IAChF,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEtC,4FAA4F;IAC5F,SAAS,KAAK,aAAa,IAAI,iBAAiB,CAE/C;IAED;;;;;;;;;OASG;IACU,OAAO,CAChB,OAAO,EAAE,YAAY,EAAE,EACvB,SAAS,EAAE,4BAA4B,EACvC,SAAS,EAAE,2BAA2B,EAAE,EACxC,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC;IAmB1B;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;YACW,oBAAoB;IAmBlC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;;;;;;;OAQG;YACW,kBAAkB;IAuBhC;;;;;;;;;OASG;YACW,eAAe;IAqD7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;YACW,kBAAkB;CA0BnC"}
@@ -1,4 +1,5 @@
1
1
  import { Metadata, RunView } from '@memberjunction/core';
2
+ import { serializeKeyValue } from './KeySerialization.js';
2
3
  /**
3
4
  * Resolves mapped records against existing MJ data to determine
4
5
  * whether each record should be Created, Updated, Skipped, or Deleted.
@@ -110,8 +111,12 @@ export class MatchEngine {
110
111
  const value = record.MappedFields[pkField.Name];
111
112
  if (value == null)
112
113
  continue;
113
- const escaped = String(value).replace(/'/g, "''");
114
- const clause = `[${pkField.Name}] = '${escaped}'`;
114
+ const escaped = serializeKeyValue(value).replace(/'/g, "''");
115
+ // ANSI double-quoted identifier — portable across SQL Server (QUOTED_IDENTIFIER ON,
116
+ // the driver default) and Postgres (exact-case; integration columns are lowercase).
117
+ // Plain identifiers break when a column name is a reserved word (e.g. a soft PK named
118
+ // `open`/`order`); brackets would fix SQL Server but break Postgres, so double-quote.
119
+ const clause = `"${pkField.Name}" = '${escaped}'`;
115
120
  if (!filterClauses.includes(clause)) {
116
121
  filterClauses.push(clause);
117
122
  }
@@ -142,8 +147,11 @@ export class MatchEngine {
142
147
  const value = record.MappedFields[kf.DestinationFieldName];
143
148
  if (value == null)
144
149
  continue;
145
- const escaped = String(value).replace(/'/g, "''");
146
- clauses.push(`[${kf.DestinationFieldName}] = '${escaped}'`);
150
+ // serializeKeyValue mirrors the write-side coercion (objects → JSON, not "[object Object]")
151
+ // so an object-valued key filters against the value actually stored in the column.
152
+ const escaped = serializeKeyValue(value).replace(/'/g, "''");
153
+ // ANSI double-quoted identifier — reserved-word-safe + portable; see CompositePK note above.
154
+ clauses.push(`"${kf.DestinationFieldName}" = '${escaped}'`);
147
155
  }
148
156
  return clauses;
149
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MatchEngine.js","sourceRoot":"","sources":["../src/MatchEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MatchEngine.js","sourceRoot":"","sources":["../src/MatchEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Generic nested-object flattening for discovery + sync record-intake.
3
+ *
4
+ * WHY (the framework bug this fixes — see memory project_connector_nested_pk_dupe):
5
+ * a source that returns NESTED records — e.g. PropFuel's
6
+ * { checkin_question: { id, checkin_id, rating, … }, contact: {…}, question: {…}, campaign: {…} }
7
+ * — folds in `discoverFromStream` as ONE object-valued column per top-level key. The soft-PK
8
+ * picker then takes the object-valued column (`checkin_question`) as the PK, because each blob is
9
+ * distinct. An object-valued PK is poison:
10
+ * 1. Identity becomes per-OCCURRENCE/per-VERSION (the blob serialized, or a `${file}:${hash}`
11
+ * fallback) instead of per-LOGICAL-RECORD, so the same record across files/versions lands as
12
+ * multiple rows → DUPLICATES.
13
+ * 2. The persisted column is an opaque JSON blob, not queryable scalar columns.
14
+ *
15
+ * Flattening BEFORE discovery makes the scalar `checkin_question_id` a column → the PK picker chooses
16
+ * a real scalar key → identity is the logical id → no dupes, and the entity is flat + queryable. The
17
+ * SAME flatten MUST run at sync record-intake so records match the discovered (flattened) schema.
18
+ *
19
+ * Behaviour:
20
+ * - Plain nested objects are flattened with `parent<sep>child` scalar keys (default sep `_`, so
21
+ * `checkin_question.id` → `checkin_question_id` — a valid MJ column name).
22
+ * - Arrays, Dates, and `null` are LEAF values (kept as-is) — arrays/Dates aren't column-flattenable;
23
+ * the write path serializes them as it already does.
24
+ * - Bounded by `maxDepth` (default 4); an object at the depth limit is kept as a leaf (blob) rather
25
+ * than recursed, so pathological deep nesting can't explode the column set.
26
+ * - A FLAT record passes through unchanged — so every existing flat-record connector is a NO-OP and
27
+ * sees zero behaviour change.
28
+ * - Key collisions (a pre-existing `a_b` colliding with a flattened `a.b`) keep the FIRST-seen value
29
+ * and are reported via `opts.onCollision` so the caller can surface it; silent overwrite is avoided.
30
+ */
31
+ export interface FlattenOptions {
32
+ /** Separator between parent and child key segments. Default `'_'`. */
33
+ Separator?: string;
34
+ /** Maximum nesting depth to flatten; objects deeper than this are kept as leaf blobs. Default 4. */
35
+ MaxDepth?: number;
36
+ /** Invoked when a flattened key collides with an existing key (first value wins). For diagnostics. */
37
+ onCollision?: (key: string) => void;
38
+ }
39
+ /**
40
+ * Returns true if `raw` contains at least one nested plain-object value — i.e. flattening would
41
+ * change it. Cheap top-level check; lets callers skip the allocation for the flat-record common case.
42
+ */
43
+ export declare function hasNestedObject(raw: Record<string, unknown>): boolean;
44
+ /**
45
+ * Flatten a record's nested plain-objects into `parent<sep>child` scalar keys. Pure; returns a new
46
+ * object. A record with no nested objects is returned shallow-copied + unchanged in shape.
47
+ */
48
+ export declare function flattenRecord(raw: Record<string, unknown>, opts?: FlattenOptions): Record<string, unknown>;
49
+ //# sourceMappingURL=RecordFlatten.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordFlatten.d.ts","sourceRoot":"","sources":["../src/RecordFlatten.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,cAAc;IAC3B,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sGAAsG;IACtG,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAaD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAKrE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,GAAE,cAAmB,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0BzB"}
@@ -0,0 +1,50 @@
1
+ const DEFAULT_SEPARATOR = '_';
2
+ const DEFAULT_MAX_DEPTH = 4;
3
+ /** A plain (non-array, non-Date) object — the only thing we recurse into. */
4
+ function isPlainObject(value) {
5
+ return value !== null
6
+ && typeof value === 'object'
7
+ && !Array.isArray(value)
8
+ && !(value instanceof Date);
9
+ }
10
+ /**
11
+ * Returns true if `raw` contains at least one nested plain-object value — i.e. flattening would
12
+ * change it. Cheap top-level check; lets callers skip the allocation for the flat-record common case.
13
+ */
14
+ export function hasNestedObject(raw) {
15
+ for (const v of Object.values(raw)) {
16
+ if (isPlainObject(v))
17
+ return true;
18
+ }
19
+ return false;
20
+ }
21
+ /**
22
+ * Flatten a record's nested plain-objects into `parent<sep>child` scalar keys. Pure; returns a new
23
+ * object. A record with no nested objects is returned shallow-copied + unchanged in shape.
24
+ */
25
+ export function flattenRecord(raw, opts = {}) {
26
+ const sep = opts.Separator ?? DEFAULT_SEPARATOR;
27
+ const maxDepth = opts.MaxDepth ?? DEFAULT_MAX_DEPTH;
28
+ const out = {};
29
+ const put = (key, value) => {
30
+ if (Object.prototype.hasOwnProperty.call(out, key)) {
31
+ opts.onCollision?.(key);
32
+ return; // first value wins
33
+ }
34
+ out[key] = value;
35
+ };
36
+ const recurse = (obj, prefix, depth) => {
37
+ for (const [k, v] of Object.entries(obj)) {
38
+ const key = prefix ? `${prefix}${sep}${k}` : k;
39
+ if (isPlainObject(v) && depth < maxDepth) {
40
+ recurse(v, key, depth + 1);
41
+ }
42
+ else {
43
+ put(key, v);
44
+ }
45
+ }
46
+ };
47
+ recurse(raw, '', 0);
48
+ return out;
49
+ }
50
+ //# sourceMappingURL=RecordFlatten.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordFlatten.js","sourceRoot":"","sources":["../src/RecordFlatten.ts"],"names":[],"mappings":"AAuCA,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,6EAA6E;AAC7E,SAAS,aAAa,CAAC,KAAc;IACjC,OAAO,KAAK,KAAK,IAAI;WACd,OAAO,KAAK,KAAK,QAAQ;WACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;WACrB,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAA4B;IACxD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,aAAa,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CACzB,GAA4B,EAC5B,OAAuB,EAAE;IAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,iBAAiB,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACpD,MAAM,GAAG,GAA4B,EAAE,CAAC;IAExC,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,KAAc,EAAQ,EAAE;QAC9C,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,CAAC,mBAAmB;QAC/B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,GAA4B,EAAE,MAAc,EAAE,KAAa,EAAQ,EAAE;QAClF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;gBACvC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAChB,CAAC;QACL,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACpB,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Time-bounded streaming discovery (the final discovery abstraction).
3
+ *
4
+ * Stage-2 of `DiscoverFields` for sources with no describe endpoint: stream the source's actual
5
+ * records (read-only — no save, no ack) and, in ONE pass, accumulate two things:
6
+ * 1. the full COLUMN corpus (every key seen) + a bounded sample of values per key for typing, and
7
+ * 2. per-column UNIQUENESS / NULL statistics — the evidence a data-informed (not nominal) PK
8
+ * decision is made from.
9
+ *
10
+ * It stops when the stream is exhausted OR a TIME BUDGET is hit — whichever comes first — and
11
+ * returns whatever it gathered. More rows → stronger claims; the budget guarantees discovery never
12
+ * runs away. Memory stays bounded regardless of row count: only the key-set + capped per-key
13
+ * sample-values + a capped distinct-set per key are retained (never the rows themselves).
14
+ *
15
+ * Pure + clock-injectable, so it's deterministically testable. Reuses {@link inferColumnTypeFromSamples}.
16
+ */
17
+ import { type InferredColumnType } from './CustomColumnPromotion.js';
18
+ export interface StreamDiscoveryOptions {
19
+ /** Wall-clock budget; once exceeded, stop and use what was gathered. Default 30s. */
20
+ TimeBudgetMs?: number;
21
+ /** Max sample values retained per column for type inference. Default 10. */
22
+ SampleValueCap?: number;
23
+ /**
24
+ * Max distinct values tracked per column before we give up proving uniqueness exactly. Beyond
25
+ * this the column is flagged `DistinctCapped` (uniqueness no longer provable from this scan, so
26
+ * it can't be a confident PK candidate). Bounds memory. Default 100000.
27
+ */
28
+ MaxDistinctTracked?: number;
29
+ /**
30
+ * Max rows whose per-cell value-hashes are retained for COMPOSITE-key discovery. Bounded memory
31
+ * (cap × columns) — never the raw values. Default 2000: enough for significance, cheap on CPU/RAM.
32
+ */
33
+ CompositeSampleRowCap?: number;
34
+ /** Injectable clock (for tests). Defaults to Date.now. */
35
+ Now?: () => number;
36
+ }
37
+ /** Per-column evidence gathered from the stream. */
38
+ export interface DiscoveredColumnStat {
39
+ Key: string;
40
+ /** Rows where the key was present + non-null. */
41
+ Occurrences: number;
42
+ /** Total rows scanned. */
43
+ TotalRows: number;
44
+ /** Distinct non-null values seen (exact, up to the cap). */
45
+ DistinctNonNull: number;
46
+ /** True if the distinct-cap was hit → uniqueness NOT provable from this scan. */
47
+ DistinctCapped: boolean;
48
+ /** Bounded sample of observed values (for type inference). */
49
+ SampleValues: unknown[];
50
+ /** Generously-bounded inferred type (both dialects). */
51
+ Inferred: InferredColumnType;
52
+ }
53
+ export interface StreamDiscoveryResult {
54
+ Columns: DiscoveredColumnStat[];
55
+ RowsScanned: number;
56
+ /** Why the scan ended — surfaced so a time-capped (partial) corpus is never silently treated as complete. */
57
+ StoppedReason: 'exhausted' | 'time-budget';
58
+ /**
59
+ * Bounded per-row cell-hash sample (column → stable value-hash for the row's non-null cells),
60
+ * capped at {@link StreamDiscoveryOptions.CompositeSampleRowCap}. Feeds composite-key discovery
61
+ * ({@link pickCompositeKeyFromStats}) without retaining raw values or every row.
62
+ */
63
+ RowSamples: Array<Record<string, string>>;
64
+ }
65
+ /**
66
+ * Streams records (sync or async iterable), accumulating the column corpus + uniqueness/null stats
67
+ * until exhaustion or the time budget. Read-only; the caller supplies whatever read-only fetch
68
+ * yields the records (no save, no ack happens here).
69
+ */
70
+ export declare function discoverFromStream(records: AsyncIterable<Record<string, unknown>> | Iterable<Record<string, unknown>>, opts?: StreamDiscoveryOptions): Promise<StreamDiscoveryResult>;
71
+ /** Options for the data-informed PK pick. */
72
+ export interface PkPickOptions {
73
+ /**
74
+ * Minimum rows scanned before a unique+non-null column is trusted as a PK (statistical
75
+ * significance — uniqueness over a tiny sample is not evidence). Default 50.
76
+ */
77
+ MinRowsForSignificance?: number;
78
+ /** A naming-rank tiebreaker, used ONLY to choose among multiple equally-unique columns. */
79
+ NameRank?: (columnName: string) => number;
80
+ /**
81
+ * Whether the scan that produced these stats SAW THE WHOLE STREAM (#A4). Default true. When false
82
+ * (the scan was time-budget-truncated), "non-null on every row + near-unique" was observed over only a
83
+ * PARTIAL prefix — a column null/duplicated solely in the unscanned tail would look like a clean key.
84
+ * So on a truncated scan the SOFT best-available fallback demands FULL prefix-uniqueness (not merely
85
+ * near-unique) and annotates the verdict that it must be re-verified on full data.
86
+ */
87
+ ScanComplete?: boolean;
88
+ }
89
+ /** The data-informed PK verdict (statistics-first). */
90
+ export interface PkStatVerdict {
91
+ /** The chosen PK column, or null when no column clears the bar. */
92
+ Field: string | null;
93
+ /** All columns that are provably unique + non-null over enough rows (the candidate set). */
94
+ UniqueCandidates: string[];
95
+ /** True when there were ≥2 unique candidates and naming couldn't break the tie → defer to the LLM tiebreaker. */
96
+ AmbiguousForLLM: boolean;
97
+ Reason: string;
98
+ }
99
+ /**
100
+ * Statistics-first PK pick from streamed evidence. A column is a candidate ONLY if it is, over a
101
+ * statistically meaningful number of rows, **non-null on every row** AND **all-distinct** (and its
102
+ * uniqueness was provable — the distinct-cap wasn't hit). One candidate → that's the PK (p<0.05:
103
+ * all-distinct over a large N is not chance). Several candidates → naming breaks the tie if it can;
104
+ * otherwise it's flagged ambiguous for the LLM tiebreaker. Zero candidates → no PK (no fabrication).
105
+ */
106
+ export declare function pickPrimaryKeyFromStats(columns: DiscoveredColumnStat[], opts?: PkPickOptions): PkStatVerdict;
107
+ /** The composite-key verdict — a provable multi-column identity, or null when none exists in the sample. */
108
+ export interface CompositePkVerdict {
109
+ /** The composite key column set (≥2 columns), or null when no provable combination was found. */
110
+ Fields: string[] | null;
111
+ Reason: string;
112
+ }
113
+ /**
114
+ * COMPOSITE PK pick from streamed evidence — for objects whose identity is a multi-column combination
115
+ * (no single column is unique). Statistics-first + provable-only, same philosophy as the single-column
116
+ * pick: it emits a column set ONLY when that set is provably unique + fully-non-null over a significant
117
+ * sample; otherwise null (→ the caller uses the content-hash identity floor). No naming guesses.
118
+ *
119
+ * Cost is GREEDY, not combinatorial — O(R·C), never the 2^C subset blow-up:
120
+ * 1. Candidate columns = those non-null on EVERY row (a null component can't be part of a stable key),
121
+ * sorted by cardinality desc (so uniqueness is reached in the fewest columns).
122
+ * 2. Greedily add the next-highest-cardinality candidate and test combined-tuple uniqueness over the
123
+ * cached per-row cell-hashes. First column set whose tuples are all-distinct over the sample wins.
124
+ * Greedy finds *a* provable unique combination (sufficient for identity/dedup), not necessarily the
125
+ * globally-minimal one — minimality is a nice-to-have the identity path doesn't need. A significance
126
+ * gate (MinRowsForSignificance) keeps a small-sample "uniqueness" from being a fluke.
127
+ */
128
+ export declare function pickCompositeKeyFromStats(columns: DiscoveredColumnStat[], rowSamples: Array<Record<string, string>>, opts?: PkPickOptions): CompositePkVerdict;
129
+ /** The unified key verdict — the chosen identity columns (1 = single PK, ≥2 = composite), or null. */
130
+ export interface KeyVerdict {
131
+ Fields: string[] | null;
132
+ Reason: string;
133
+ }
134
+ /**
135
+ * Provable-only key pick — single OR composite, in ONE pass. Picks the BEST contender at each subset
136
+ * size (1, 2, 3 …), then takes the SMALLEST size whose best contender is a provable key (minimality:
137
+ * a 1-col key beats a 2-col beats a 3-col). "Best" + "is it a key" are the same Chao1 saturation test
138
+ * ({@link subsetKeyness}) applied to the subset's combined tuple — no arbitrary distinct-ratio. If NO
139
+ * size yields a provable key, returns null (the object is honestly keyless — never a fabricated key).
140
+ */
141
+ export declare function pickKeyFromStats(columns: DiscoveredColumnStat[], rowSamples: Array<Record<string, string>>, opts?: PkPickOptions & {
142
+ MaxKeyColumns?: number;
143
+ MaxCandidates?: number;
144
+ }): KeyVerdict;
145
+ //# sourceMappingURL=StreamingDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamingDiscovery.d.ts","sourceRoot":"","sources":["../src/StreamingDiscovery.ts"],"names":[],"mappings":"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"}