@memberjunction/record-set-processor-base 0.0.1 → 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 (42) hide show
  1. package/README.md +51 -43
  2. package/dist/index.d.ts +9 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +9 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/interfaces.d.ts +165 -0
  7. package/dist/interfaces.d.ts.map +1 -0
  8. package/dist/interfaces.js +8 -0
  9. package/dist/interfaces.js.map +1 -0
  10. package/dist/sources/arraySource.d.ts +22 -0
  11. package/dist/sources/arraySource.d.ts.map +1 -0
  12. package/dist/sources/arraySource.js +33 -0
  13. package/dist/sources/arraySource.js.map +1 -0
  14. package/dist/sources/filterSource.d.ts +23 -0
  15. package/dist/sources/filterSource.d.ts.map +1 -0
  16. package/dist/sources/filterSource.js +38 -0
  17. package/dist/sources/filterSource.js.map +1 -0
  18. package/dist/sources/index.d.ts +11 -0
  19. package/dist/sources/index.d.ts.map +1 -0
  20. package/dist/sources/index.js +11 -0
  21. package/dist/sources/index.js.map +1 -0
  22. package/dist/sources/keysetSource.d.ts +24 -0
  23. package/dist/sources/keysetSource.d.ts.map +1 -0
  24. package/dist/sources/keysetSource.js +42 -0
  25. package/dist/sources/keysetSource.js.map +1 -0
  26. package/dist/sources/listSource.d.ts +19 -0
  27. package/dist/sources/listSource.d.ts.map +1 -0
  28. package/dist/sources/listSource.js +64 -0
  29. package/dist/sources/listSource.js.map +1 -0
  30. package/dist/sources/sourceUtil.d.ts +30 -0
  31. package/dist/sources/sourceUtil.d.ts.map +1 -0
  32. package/dist/sources/sourceUtil.js +87 -0
  33. package/dist/sources/sourceUtil.js.map +1 -0
  34. package/dist/sources/viewSource.d.ts +20 -0
  35. package/dist/sources/viewSource.d.ts.map +1 -0
  36. package/dist/sources/viewSource.js +62 -0
  37. package/dist/sources/viewSource.js.map +1 -0
  38. package/dist/types.d.ts +100 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +8 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +29 -7
package/README.md CHANGED
@@ -1,45 +1,53 @@
1
1
  # @memberjunction/record-set-processor-base
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/record-set-processor-base`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
3
+ Client-safe foundation for the MemberJunction **Record Set Processing** substrate: the shared types,
4
+ the three pluggable seams, and the built-in source adapters. The server engine that drives these
5
+ lives in [`@memberjunction/record-set-processor`](../engine).
6
+
7
+ ## What's in here
8
+
9
+ | Export | Kind | Purpose |
10
+ |---|---|---|
11
+ | `IRecordSetSource` | seam | yields the record set in cursor-paginated batches |
12
+ | `IRecordProcessor` | seam | does the work for a single record |
13
+ | `IProcessRunTracker` | seam | persists run lifecycle, per-record detail, checkpoints, pause/cancel |
14
+ | `RecordSetProcessOptions` | type | the engine's per-run options |
15
+ | `RecordRef`, `RecordBatch`, `ProcessCursor`, `RecordResult`, `ProcessRunResult`, … | types | the data shapes shared across the seams |
16
+ | `ArraySource`, `ViewSource`, `ListSource`, `FilterSource`, `KeysetSource` | sources | the built-in record-set sources |
17
+
18
+ ## The three seams
19
+
20
+ A processing job is a composition of three independent choices:
21
+
22
+ - **Source** *what* records to iterate (a User View, a List, an ad-hoc filter, an in-memory array,
23
+ or a keyset sweep). Sources paginate themselves and hand back an opaque `ProcessCursor` the engine
24
+ round-trips for resume.
25
+ - **Processor** *what to do* with each record (an Action, an Agent, an Infer-&-Write-Back step, or
26
+ a function), returning a `RecordResult` (`Succeeded` / `Failed` / `Skipped`).
27
+ - **Tracker** *where to persist* run + per-record audit. The default writes the generic
28
+ `MJ: Process Runs` / `MJ: Process Run Details` tables; domain consumers can supply their own.
29
+
30
+ ## Source adapters
31
+
32
+ | Source | Pagination | Notes |
33
+ |---|---|---|
34
+ | `ArraySource` | offset (in-memory) | a fixed list of `RecordRef`; also use for `SingleRecord` scopes |
35
+ | `ViewSource` | offset | resolves a saved User View; views may carry arbitrary order/filter so offset is used |
36
+ | `ListSource` | offset | iterates a List's members via `MJ: List Details` |
37
+ | `FilterSource` | keyset → offset | entity + ad-hoc WHERE; keyset when the entity has a single orderable PK |
38
+ | `KeysetSource` | keyset (required) | like `FilterSource` but asserts keyset eligibility — for large background sweeps |
39
+
40
+ ## Implementing a source
41
+
42
+ ```typescript
43
+ import { IRecordSetSource, RecordBatch, ProcessCursor, SourceDescriptor } from '@memberjunction/record-set-processor-base';
44
+
45
+ export class MySource implements IRecordSetSource {
46
+ Describe(): SourceDescriptor { return { SourceType: 'Filter', SourceFilter: '...' }; }
47
+ async NextBatch(cursor: ProcessCursor | undefined, batchSize: number, contextUser, provider): Promise<RecordBatch> {
48
+ // fetch up to `batchSize` records after `cursor`, return them plus the next cursor + exhausted flag
49
+ }
50
+ }
51
+ ```
52
+
53
+ This package carries no server-only dependencies and is safe to import on the client.
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Public API for the Record Set Processor base package — client-safe types, the three
3
+ * pluggable seams (source / processor / tracker), and the built-in source adapters.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ export * from './types.js';
7
+ export * from './interfaces.js';
8
+ export * from './sources/index.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Public API for the Record Set Processor base package — client-safe types, the three
3
+ * pluggable seams (source / processor / tracker), and the built-in source adapters.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ export * from './types.js';
7
+ export * from './interfaces.js';
8
+ export * from './sources/index.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * @fileoverview The three pluggable seams of the Record Set Processor — source, processor, and
3
+ * persistence tracker — plus the engine's options shape. The engine ({@link
4
+ * @memberjunction/record-set-processor}) routes every set-iterating job through these interfaces.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
8
+ import { ProcessCursor, ProcessRunSummary, ProgressInfo, RecordBatch, RecordRef, RecordResult, RunCounts, SourceTypeValue, TriggeredByValue } from './types.js';
9
+ /** Lightweight, persistable description of a source — used to populate the run header. */
10
+ export interface SourceDescriptor {
11
+ /** The kind of source (View / List / Filter / Array / Keyset / SingleRecord). */
12
+ SourceType: SourceTypeValue;
13
+ /** The source's defining ID (ViewID or ListID) when applicable. */
14
+ SourceID?: string;
15
+ /** The source's resolved filter snapshot, when applicable. */
16
+ SourceFilter?: string;
17
+ /** The target entity ID, when the source knows it up-front. */
18
+ EntityID?: string;
19
+ }
20
+ /**
21
+ * SOURCE seam — yields the record set in cursor-paginated batches. Implementations decide their own
22
+ * pagination strategy (offset vs. keyset); the cursor is opaque to the engine and round-tripped
23
+ * through the tracker for resume.
24
+ */
25
+ export interface IRecordSetSource {
26
+ /**
27
+ * Returns the next batch of records after the given cursor.
28
+ * @param cursor - The cursor returned by the previous batch, or `undefined` to start from the beginning.
29
+ * @param batchSize - Maximum number of records to return.
30
+ * @param contextUser - The acting user (required server-side for permissions).
31
+ * @param provider - Optional metadata provider for entity resolution.
32
+ * @returns A batch with the records, the next cursor, and an exhausted flag.
33
+ */
34
+ NextBatch(cursor: ProcessCursor | undefined, batchSize: number, contextUser: UserInfo, provider?: IMetadataProvider): Promise<RecordBatch>;
35
+ /** Returns a persistable description of this source for the run header. */
36
+ Describe(): SourceDescriptor;
37
+ }
38
+ /** Per-record execution context handed to an {@link IRecordProcessor}. */
39
+ export interface RecordProcessorContext {
40
+ /** The acting user. */
41
+ contextUser: UserInfo;
42
+ /** The owning provider — use this for data access (never `new Metadata()`), per the multi-provider rule. */
43
+ provider: IMetadataProvider;
44
+ /** ID of the current process run, when one is being tracked. */
45
+ processRunID?: string;
46
+ }
47
+ /**
48
+ * PROCESSOR (executor) seam — does the work for a single record and returns its outcome. Concrete
49
+ * processors wrap an Action, an Agent (via Execute Agent), an Infer-&-Write-Back step, or a plain
50
+ * function.
51
+ */
52
+ export interface IRecordProcessor {
53
+ /**
54
+ * Processes one record.
55
+ * @param record - The record to process.
56
+ * @param context - The per-record execution context.
57
+ * @returns The record's outcome (Succeeded / Failed / Skipped) plus any payload / trace links.
58
+ */
59
+ ProcessRecord(record: RecordRef, context: RecordProcessorContext): Promise<RecordResult>;
60
+ }
61
+ /** Opaque handle returned by a tracker's `BeginRun`, threaded back through the other tracker calls. */
62
+ export interface RunHandle {
63
+ /** ID of the persisted run, when the tracker persists one. */
64
+ ProcessRunID?: string;
65
+ /** Tracker-private state. */
66
+ [key: string]: unknown;
67
+ }
68
+ /** Metadata describing a run, supplied to a tracker's `BeginRun`. */
69
+ export interface ProcessRunMeta {
70
+ /** FK to the originating Record Process definition (NULL for ad-hoc / engine-driven runs). */
71
+ RecordProcessID?: string;
72
+ /** FK to the owning `ScheduledJobRun` when launched by the scheduler (NULL otherwise). */
73
+ ScheduledJobRunID?: string;
74
+ /** FK to the target entity. */
75
+ EntityID?: string;
76
+ /** What triggered the run. */
77
+ TriggeredBy: TriggeredByValue;
78
+ /** The kind of source. */
79
+ SourceType: SourceTypeValue;
80
+ /** ViewID / ListID, when applicable. */
81
+ SourceID?: string;
82
+ /** Resolved filter snapshot, when applicable. */
83
+ SourceFilter?: string;
84
+ /** Effective batch size. */
85
+ BatchSize?: number;
86
+ /** Known total record count, or null. */
87
+ TotalItemCount?: number | null;
88
+ /** JSON-serializable snapshot of the effective configuration. */
89
+ Configuration?: unknown;
90
+ }
91
+ /**
92
+ * PERSISTENCE seam — records run lifecycle, per-record detail, checkpoints, and the pause/cancel
93
+ * handshake. The default `GenericProcessRunTracker` (in the engine package) writes `MJ: Process
94
+ * Runs` / `MJ: Process Run Details`; domain consumers can supply their own (e.g. the classifier's
95
+ * Content Process Runs), and `NoOpTracker` discards everything for fire-and-forget single-record work.
96
+ */
97
+ export interface IProcessRunTracker {
98
+ /** Begins a run and returns a handle threaded through the remaining calls. */
99
+ BeginRun(meta: ProcessRunMeta, contextUser: UserInfo, provider?: IMetadataProvider): Promise<RunHandle>;
100
+ /** Records the outcome of a single processed record. */
101
+ RecordResult(handle: RunHandle, record: RecordRef, result: RecordResult, contextUser: UserInfo, provider?: IMetadataProvider): Promise<void>;
102
+ /**
103
+ * Persists the resume cursor + running counts after a batch and reports whether to continue.
104
+ * Implementations that support pause/cancel re-check their backing row's cancellation flag here
105
+ * and return `false` to request a graceful pause.
106
+ * @returns `true` to continue, `false` to pause/stop.
107
+ */
108
+ Checkpoint(handle: RunHandle, cursor: ProcessCursor, counts: RunCounts, contextUser: UserInfo, provider?: IMetadataProvider): Promise<boolean>;
109
+ /** Finalizes the run with its terminal status + summary counts. */
110
+ CompleteRun(handle: RunHandle, summary: ProcessRunSummary, contextUser: UserInfo, provider?: IMetadataProvider): Promise<void>;
111
+ /** Loads the resume cursor for a run being resumed, or `undefined` to start from the beginning. */
112
+ LoadResumeCursor(handle: RunHandle, contextUser: UserInfo, provider?: IMetadataProvider): Promise<ProcessCursor | undefined>;
113
+ }
114
+ /** Options for a single `RecordSetProcessor.Process()` invocation. */
115
+ export interface RecordSetProcessOptions {
116
+ /** The record-set source to iterate. */
117
+ source: IRecordSetSource;
118
+ /** The per-record processor (executor). */
119
+ processor: IRecordProcessor;
120
+ /** Persistence tracker (defaults to `GenericProcessRunTracker` in the engine). */
121
+ tracker?: IProcessRunTracker;
122
+ /** The acting user (required). */
123
+ contextUser: UserInfo;
124
+ /** The owning provider; defaults to the active provider when omitted. */
125
+ provider?: IMetadataProvider;
126
+ /** Optional FK to the originating Record Process definition. */
127
+ recordProcessID?: string;
128
+ /** Optional FK to the owning `ScheduledJobRun` when launched by the scheduler. */
129
+ scheduledJobRunID?: string;
130
+ /** Optional target entity ID (otherwise derived from the source). */
131
+ entityID?: string;
132
+ /** What triggered the run (default `Manual`). */
133
+ triggeredBy?: TriggeredByValue;
134
+ /** Records per batch (default 100). */
135
+ batchSize?: number;
136
+ /** Maximum records processed concurrently within a batch (default 1). */
137
+ maxConcurrency?: number;
138
+ /** Error-rate circuit breaker threshold, as a percentage (default 20). */
139
+ errorThresholdPercent?: number;
140
+ /** Delay between batches in milliseconds (default 0). */
141
+ delayBetweenBatchesMs?: number;
142
+ /** Optional rate-limit applied once per batch before processing. */
143
+ rateLimit?: {
144
+ requestsPerMinute?: number;
145
+ tokensPerMinute?: number;
146
+ };
147
+ /** Whether to resume from a prior checkpoint when one exists (default true). */
148
+ resume?: boolean;
149
+ /** Hard cap on the number of records processed this run. */
150
+ maxRecords?: number;
151
+ /** Progress callback invoked after each batch. */
152
+ onProgress?: (progress: ProgressInfo) => void;
153
+ /**
154
+ * Budget-gate hook invoked after each batch. Return `{ continue: false, reason }` to pause the
155
+ * run (e.g. when a per-run cost/item budget is exhausted).
156
+ */
157
+ onAfterBatch?: (batch: RecordRef[], processed: number) => Promise<{
158
+ continue: boolean;
159
+ reason?: string;
160
+ } | null>;
161
+ /** JSON-serializable snapshot of configuration, persisted on the run header. */
162
+ configuration?: unknown;
163
+ }
164
+ export type { ProgressInfo, ProcessRunSummary };
165
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview The three pluggable seams of the Record Set Processor — source, processor, and
3
+ * persistence tracker — plus the engine's options shape. The engine ({@link
4
+ * @memberjunction/record-set-processor}) routes every set-iterating job through these interfaces.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview In-memory array source — yields a fixed list of record references in batches.
3
+ * Useful for `SingleRecord` / explicit-array scopes and for tests.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ import { IRecordSetSource, SourceDescriptor } from '../interfaces.js';
7
+ import { ProcessCursor, RecordBatch, RecordRef, SourceTypeValue } from '../types.js';
8
+ /** A source backed by an in-memory array of {@link RecordRef}. */
9
+ export declare class ArraySource implements IRecordSetSource {
10
+ private readonly records;
11
+ private readonly entityID?;
12
+ private readonly sourceType;
13
+ /**
14
+ * @param records - The records to yield.
15
+ * @param entityID - Optional entity ID for the run header (otherwise taken from the first record).
16
+ * @param sourceType - Reported source type (default `Array`; pass `SingleRecord` for a one-record scope).
17
+ */
18
+ constructor(records: RecordRef[], entityID?: string, sourceType?: SourceTypeValue);
19
+ Describe(): SourceDescriptor;
20
+ NextBatch(cursor: ProcessCursor | undefined, batchSize: number): Promise<RecordBatch>;
21
+ }
22
+ //# sourceMappingURL=arraySource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arraySource.d.ts","sourceRoot":"","sources":["../../src/sources/arraySource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAElF,kEAAkE;AAClE,qBAAa,WAAY,YAAW,gBAAgB;IAO5C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR/B;;;;OAIG;gBAEkB,OAAO,EAAE,SAAS,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,GAAE,eAAyB;IAGnD,QAAQ,IAAI,gBAAgB;IAItB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAWrG"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @fileoverview In-memory array source — yields a fixed list of record references in batches.
3
+ * Useful for `SingleRecord` / explicit-array scopes and for tests.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ /** A source backed by an in-memory array of {@link RecordRef}. */
7
+ export class ArraySource {
8
+ /**
9
+ * @param records - The records to yield.
10
+ * @param entityID - Optional entity ID for the run header (otherwise taken from the first record).
11
+ * @param sourceType - Reported source type (default `Array`; pass `SingleRecord` for a one-record scope).
12
+ */
13
+ constructor(records, entityID, sourceType = 'Array') {
14
+ this.records = records;
15
+ this.entityID = entityID;
16
+ this.sourceType = sourceType;
17
+ }
18
+ Describe() {
19
+ return { SourceType: this.sourceType, EntityID: this.entityID ?? this.records[0]?.EntityID };
20
+ }
21
+ async NextBatch(cursor, batchSize) {
22
+ const offset = cursor?.Offset ?? 0;
23
+ const slice = this.records.slice(offset, offset + batchSize);
24
+ const next = offset + slice.length;
25
+ return {
26
+ Records: slice,
27
+ NextCursor: { Offset: next },
28
+ Exhausted: next >= this.records.length,
29
+ TotalRowCount: this.records.length,
30
+ };
31
+ }
32
+ }
33
+ //# sourceMappingURL=arraySource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arraySource.js","sourceRoot":"","sources":["../../src/sources/arraySource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,kEAAkE;AAClE,MAAM,OAAO,WAAW;IACpB;;;;OAIG;IACH,YACqB,OAAoB,EACpB,QAAiB,EACjB,aAA8B,OAAO;QAFrC,YAAO,GAAP,OAAO,CAAa;QACpB,aAAQ,GAAR,QAAQ,CAAS;QACjB,eAAU,GAAV,UAAU,CAA2B;IACvD,CAAC;IAEG,QAAQ;QACX,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;IACjG,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,MAAiC,EAAE,SAAiB;QACvE,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACnC,OAAO;YACH,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;YAC5B,SAAS,EAAE,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM;YACtC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;SACrC,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Filter source — iterates an entity's rows matching an ad-hoc WHERE clause. Uses
3
+ * keyset (seek) pagination when the entity has a single orderable PK, otherwise offset.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ import { EntityInfo, IMetadataProvider, UserInfo } from '@memberjunction/core';
7
+ import { IRecordSetSource, SourceDescriptor } from '../interfaces.js';
8
+ import { ProcessCursor, RecordBatch } from '../types.js';
9
+ /** A source backed by an entity + ad-hoc filter. */
10
+ export declare class FilterSource implements IRecordSetSource {
11
+ private readonly entityName;
12
+ private readonly filter?;
13
+ private entity?;
14
+ /**
15
+ * @param entityName - The target entity name.
16
+ * @param filter - Optional WHERE clause (no leading `WHERE`).
17
+ */
18
+ constructor(entityName: string, filter?: string);
19
+ Describe(): SourceDescriptor;
20
+ protected resolveEntity(provider?: IMetadataProvider): EntityInfo;
21
+ NextBatch(cursor: ProcessCursor | undefined, batchSize: number, contextUser: UserInfo, provider?: IMetadataProvider): Promise<RecordBatch>;
22
+ }
23
+ //# sourceMappingURL=filterSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filterSource.d.ts","sourceRoot":"","sources":["../../src/sources/filterSource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGtD,oDAAoD;AACpD,qBAAa,YAAa,YAAW,gBAAgB;IAOrC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IANzE,OAAO,CAAC,MAAM,CAAC,CAAa;IAE5B;;;OAGG;gBAC0B,UAAU,EAAE,MAAM,EAAmB,MAAM,CAAC,EAAE,MAAM;IAE1E,QAAQ,IAAI,gBAAgB;IAInC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,UAAU;IAapD,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;CAI1J"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview Filter source — iterates an entity's rows matching an ad-hoc WHERE clause. Uses
3
+ * keyset (seek) pagination when the entity has a single orderable PK, otherwise offset.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ import { Metadata } from '@memberjunction/core';
7
+ import { pageEntityByFilter } from './sourceUtil.js';
8
+ /** A source backed by an entity + ad-hoc filter. */
9
+ export class FilterSource {
10
+ /**
11
+ * @param entityName - The target entity name.
12
+ * @param filter - Optional WHERE clause (no leading `WHERE`).
13
+ */
14
+ constructor(entityName, filter) {
15
+ this.entityName = entityName;
16
+ this.filter = filter;
17
+ }
18
+ Describe() {
19
+ return { SourceType: 'Filter', SourceFilter: this.filter, EntityID: this.entity?.ID };
20
+ }
21
+ resolveEntity(provider) {
22
+ if (this.entity) {
23
+ return this.entity;
24
+ }
25
+ const md = provider ?? Metadata.Provider;
26
+ const entity = md.EntityByName(this.entityName);
27
+ if (!entity) {
28
+ throw new Error(`FilterSource: entity '${this.entityName}' not found in metadata`);
29
+ }
30
+ this.entity = entity;
31
+ return entity;
32
+ }
33
+ async NextBatch(cursor, batchSize, contextUser, provider) {
34
+ const entity = this.resolveEntity(provider);
35
+ return pageEntityByFilter({ entity, filter: this.filter, cursor, batchSize, contextUser, preferKeyset: true });
36
+ }
37
+ }
38
+ //# sourceMappingURL=filterSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filterSource.js","sourceRoot":"","sources":["../../src/sources/filterSource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiC,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAGzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,oDAAoD;AACpD,MAAM,OAAO,YAAY;IAGrB;;;OAGG;IACH,YAA6B,UAAkB,EAAmB,MAAe;QAApD,eAAU,GAAV,UAAU,CAAQ;QAAmB,WAAM,GAAN,MAAM,CAAS;IAAG,CAAC;IAE9E,QAAQ;QACX,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC;IAC1F,CAAC;IAES,aAAa,CAAC,QAA4B;QAChD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,MAAM,EAAE,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,UAAU,yBAAyB,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,MAAiC,EAAE,SAAiB,EAAE,WAAqB,EAAE,QAA4B;QAC5H,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACnH,CAAC;CACJ"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Barrel for the built-in record-set source adapters.
3
+ * @module @memberjunction/record-set-processor-base
4
+ */
5
+ export * from './sourceUtil.js';
6
+ export * from './arraySource.js';
7
+ export * from './viewSource.js';
8
+ export * from './listSource.js';
9
+ export * from './filterSource.js';
10
+ export * from './keysetSource.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Barrel for the built-in record-set source adapters.
3
+ * @module @memberjunction/record-set-processor-base
4
+ */
5
+ export * from './sourceUtil.js';
6
+ export * from './arraySource.js';
7
+ export * from './viewSource.js';
8
+ export * from './listSource.js';
9
+ export * from './filterSource.js';
10
+ export * from './keysetSource.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview Keyset source — like {@link FilterSource} but explicitly requires keyset (seek)
3
+ * pagination, asserting the entity has a single orderable PK. Preferred for large background sweeps
4
+ * where deep offset pagination would degrade. Reports `SourceType: 'Keyset'`.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
8
+ import { IRecordSetSource, SourceDescriptor } from '../interfaces.js';
9
+ import { ProcessCursor, RecordBatch } from '../types.js';
10
+ /** A source backed by an entity + ad-hoc filter, paginated strictly via keyset. */
11
+ export declare class KeysetSource implements IRecordSetSource {
12
+ private readonly entityName;
13
+ private readonly filter?;
14
+ private entity?;
15
+ /**
16
+ * @param entityName - The target entity name (must have a single orderable PK).
17
+ * @param filter - Optional WHERE clause (no leading `WHERE`).
18
+ */
19
+ constructor(entityName: string, filter?: string);
20
+ Describe(): SourceDescriptor;
21
+ private resolveEntity;
22
+ NextBatch(cursor: ProcessCursor | undefined, batchSize: number, contextUser: UserInfo, provider?: IMetadataProvider): Promise<RecordBatch>;
23
+ }
24
+ //# sourceMappingURL=keysetSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keysetSource.d.ts","sourceRoot":"","sources":["../../src/sources/keysetSource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGtD,mFAAmF;AACnF,qBAAa,YAAa,YAAW,gBAAgB;IAOrC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IANzE,OAAO,CAAC,MAAM,CAAC,CAAa;IAE5B;;;OAGG;gBAC0B,UAAU,EAAE,MAAM,EAAmB,MAAM,CAAC,EAAE,MAAM;IAE1E,QAAQ,IAAI,gBAAgB;IAInC,OAAO,CAAC,aAAa;IAgBR,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;CAI1J"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @fileoverview Keyset source — like {@link FilterSource} but explicitly requires keyset (seek)
3
+ * pagination, asserting the entity has a single orderable PK. Preferred for large background sweeps
4
+ * where deep offset pagination would degrade. Reports `SourceType: 'Keyset'`.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { Metadata } from '@memberjunction/core';
8
+ import { canUseKeyset, pageEntityByFilter } from './sourceUtil.js';
9
+ /** A source backed by an entity + ad-hoc filter, paginated strictly via keyset. */
10
+ export class KeysetSource {
11
+ /**
12
+ * @param entityName - The target entity name (must have a single orderable PK).
13
+ * @param filter - Optional WHERE clause (no leading `WHERE`).
14
+ */
15
+ constructor(entityName, filter) {
16
+ this.entityName = entityName;
17
+ this.filter = filter;
18
+ }
19
+ Describe() {
20
+ return { SourceType: 'Keyset', SourceFilter: this.filter, EntityID: this.entity?.ID };
21
+ }
22
+ resolveEntity(provider) {
23
+ if (this.entity) {
24
+ return this.entity;
25
+ }
26
+ const md = provider ?? Metadata.Provider;
27
+ const entity = md.EntityByName(this.entityName);
28
+ if (!entity) {
29
+ throw new Error(`KeysetSource: entity '${this.entityName}' not found in metadata`);
30
+ }
31
+ if (!canUseKeyset(entity)) {
32
+ throw new Error(`KeysetSource: entity '${this.entityName}' lacks a single orderable PK; use FilterSource instead`);
33
+ }
34
+ this.entity = entity;
35
+ return entity;
36
+ }
37
+ async NextBatch(cursor, batchSize, contextUser, provider) {
38
+ const entity = this.resolveEntity(provider);
39
+ return pageEntityByFilter({ entity, filter: this.filter, cursor, batchSize, contextUser, preferKeyset: true });
40
+ }
41
+ }
42
+ //# sourceMappingURL=keysetSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keysetSource.js","sourceRoot":"","sources":["../../src/sources/keysetSource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAiC,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAGzF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEhE,mFAAmF;AACnF,MAAM,OAAO,YAAY;IAGrB;;;OAGG;IACH,YAA6B,UAAkB,EAAmB,MAAe;QAApD,eAAU,GAAV,UAAU,CAAQ;QAAmB,WAAM,GAAN,MAAM,CAAS;IAAG,CAAC;IAE9E,QAAQ;QACX,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC;IAC1F,CAAC;IAEO,aAAa,CAAC,QAA4B;QAC9C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,MAAM,EAAE,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,UAAU,yBAAyB,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,UAAU,yDAAyD,CAAC,CAAC;QACvH,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,MAAiC,EAAE,SAAiB,EAAE,WAAqB,EAAE,QAA4B;QAC5H,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACnH,CAAC;CACJ"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview List source — yields the members of an `MJ: Lists` record (read from `MJ: List
3
+ * Details`) in offset-paginated batches. List Details already store a composite-key-safe `RecordID`.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
7
+ import { IRecordSetSource, SourceDescriptor } from '../interfaces.js';
8
+ import { ProcessCursor, RecordBatch } from '../types.js';
9
+ /** A source backed by a List (its members, via List Details). */
10
+ export declare class ListSource implements IRecordSetSource {
11
+ private readonly listID;
12
+ private entityID?;
13
+ /** @param listID - The `MJ: Lists` ID whose members to iterate. */
14
+ constructor(listID: string);
15
+ Describe(): SourceDescriptor;
16
+ private resolveEntityID;
17
+ NextBatch(cursor: ProcessCursor | undefined, batchSize: number, contextUser: UserInfo, _provider?: IMetadataProvider): Promise<RecordBatch>;
18
+ }
19
+ //# sourceMappingURL=listSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listSource.d.ts","sourceRoot":"","sources":["../../src/sources/listSource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAW,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAa,MAAM,UAAU,CAAC;AAEjE,iEAAiE;AACjE,qBAAa,UAAW,YAAW,gBAAgB;IAInC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,CAAS;IAE1B,mEAAmE;gBACtC,MAAM,EAAE,MAAM;IAEpC,QAAQ,IAAI,gBAAgB;YAIrB,eAAe;IAuBhB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;CAyB3J"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @fileoverview List source — yields the members of an `MJ: Lists` record (read from `MJ: List
3
+ * Details`) in offset-paginated batches. List Details already store a composite-key-safe `RecordID`.
4
+ * @module @memberjunction/record-set-processor-base
5
+ */
6
+ import { RunView } from '@memberjunction/core';
7
+ /** A source backed by a List (its members, via List Details). */
8
+ export class ListSource {
9
+ /** @param listID - The `MJ: Lists` ID whose members to iterate. */
10
+ constructor(listID) {
11
+ this.listID = listID;
12
+ }
13
+ Describe() {
14
+ return { SourceType: 'List', SourceID: this.listID, EntityID: this.entityID };
15
+ }
16
+ async resolveEntityID(contextUser) {
17
+ if (this.entityID) {
18
+ return this.entityID;
19
+ }
20
+ const rv = new RunView();
21
+ const result = await rv.RunView({
22
+ EntityName: 'MJ: Lists',
23
+ ExtraFilter: `ID='${this.listID}'`,
24
+ Fields: ['EntityID'],
25
+ ResultType: 'simple',
26
+ MaxRows: 1,
27
+ }, contextUser);
28
+ if (!result.Success) {
29
+ throw new Error(`ListSource: failed loading list '${this.listID}': ${result.ErrorMessage}`);
30
+ }
31
+ const row = (result.Results ?? [])[0];
32
+ if (!row?.EntityID) {
33
+ throw new Error(`ListSource: list '${this.listID}' not found`);
34
+ }
35
+ this.entityID = row.EntityID;
36
+ return this.entityID;
37
+ }
38
+ async NextBatch(cursor, batchSize, contextUser, _provider) {
39
+ const entityID = await this.resolveEntityID(contextUser);
40
+ const offset = cursor?.Offset ?? 0;
41
+ const rv = new RunView();
42
+ const result = await rv.RunView({
43
+ EntityName: 'MJ: List Details',
44
+ ExtraFilter: `ListID='${this.listID}'`,
45
+ Fields: ['RecordID'],
46
+ OrderBy: 'ID',
47
+ ResultType: 'simple',
48
+ StartRow: offset,
49
+ MaxRows: batchSize,
50
+ }, contextUser);
51
+ if (!result.Success) {
52
+ throw new Error(`ListSource: failed loading members for list '${this.listID}': ${result.ErrorMessage}`);
53
+ }
54
+ const rows = (result.Results ?? []);
55
+ const records = rows.map((row) => ({ EntityID: entityID, RecordID: String(row.RecordID) }));
56
+ return {
57
+ Records: records,
58
+ NextCursor: { Offset: offset + records.length },
59
+ Exhausted: records.length < batchSize,
60
+ TotalRowCount: result.TotalRowCount,
61
+ };
62
+ }
63
+ }
64
+ //# sourceMappingURL=listSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listSource.js","sourceRoot":"","sources":["../../src/sources/listSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Shared helpers for source adapters: composite-key-safe record-ID serialization,
3
+ * keyset-pagination eligibility, and a generic entity-filter pager that picks keyset (seek) or
4
+ * offset pagination as appropriate.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { EntityInfo, UserInfo } from '@memberjunction/core';
8
+ import { ProcessCursor, RecordBatch } from '../types.js';
9
+ /**
10
+ * Serializes a record's primary key to a composite-key-safe string. Single-PK entities return the
11
+ * raw value; composite-PK entities use `CompositeKey.ToConcatenatedString()`.
12
+ */
13
+ export declare function serializeRecordId(entity: EntityInfo, row: Record<string, unknown>): string;
14
+ /** Returns true when the entity has a single, orderable primary key suitable for keyset pagination. */
15
+ export declare function canUseKeyset(entity: EntityInfo): boolean;
16
+ /**
17
+ * Pages an entity's rows by filter, returning one batch of {@link RecordRef}. Uses keyset (seek)
18
+ * pagination when `preferKeyset` is set and the entity supports it (single orderable PK), otherwise
19
+ * falls back to offset (StartRow) pagination. Selects only the PK columns and bypasses the cache —
20
+ * these single-use sweep pages should never pollute the local cache.
21
+ */
22
+ export declare function pageEntityByFilter(opts: {
23
+ entity: EntityInfo;
24
+ filter?: string;
25
+ cursor: ProcessCursor | undefined;
26
+ batchSize: number;
27
+ contextUser: UserInfo;
28
+ preferKeyset: boolean;
29
+ }): Promise<RecordBatch>;
30
+ //# sourceMappingURL=sourceUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceUtil.d.ts","sourceRoot":"","sources":["../../src/sources/sourceUtil.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgB,UAAU,EAAW,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAa,MAAM,UAAU,CAAC;AAYjE;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAO1F;AAED,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CASxD;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,WAAW,CAAC,CA6CvB"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @fileoverview Shared helpers for source adapters: composite-key-safe record-ID serialization,
3
+ * keyset-pagination eligibility, and a generic entity-filter pager that picks keyset (seek) or
4
+ * offset pagination as appropriate.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { CompositeKey, RunView } from '@memberjunction/core';
8
+ /** PK column types over which keyset (seek) pagination is safe and stable. */
9
+ const KEYSET_ORDERABLE_PK_TYPES = new Set([
10
+ 'uniqueidentifier', 'uuid', 'int', 'integer', 'bigint', 'smallint', 'tinyint',
11
+ 'decimal', 'numeric', 'money', 'smallmoney', 'float', 'real', 'double precision',
12
+ 'char', 'varchar', 'nchar', 'nvarchar', 'character', 'character varying',
13
+ 'date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time',
14
+ 'timestamp', 'timestamp with time zone', 'timestamp without time zone',
15
+ 'bit', 'boolean', 'serial', 'bigserial',
16
+ ]);
17
+ /**
18
+ * Serializes a record's primary key to a composite-key-safe string. Single-PK entities return the
19
+ * raw value; composite-PK entities use `CompositeKey.ToConcatenatedString()`.
20
+ */
21
+ export function serializeRecordId(entity, row) {
22
+ if (entity.PrimaryKeys.length === 1) {
23
+ return String(row[entity.PrimaryKeys[0].Name]);
24
+ }
25
+ const ck = new CompositeKey();
26
+ ck.KeyValuePairs = entity.PrimaryKeys.map((pk) => ({ FieldName: pk.Name, Value: row[pk.Name] }));
27
+ return ck.ToConcatenatedString();
28
+ }
29
+ /** Returns true when the entity has a single, orderable primary key suitable for keyset pagination. */
30
+ export function canUseKeyset(entity) {
31
+ if (!entity.FirstPrimaryKey || entity.PrimaryKeys.length !== 1) {
32
+ return false;
33
+ }
34
+ const normalizedType = (entity.FirstPrimaryKey.Type || '')
35
+ .replace(/\s*\([^)]*\)\s*$/, '') // strip parameterization like "nvarchar(255)"
36
+ .trim()
37
+ .toLowerCase();
38
+ return KEYSET_ORDERABLE_PK_TYPES.has(normalizedType);
39
+ }
40
+ /**
41
+ * Pages an entity's rows by filter, returning one batch of {@link RecordRef}. Uses keyset (seek)
42
+ * pagination when `preferKeyset` is set and the entity supports it (single orderable PK), otherwise
43
+ * falls back to offset (StartRow) pagination. Selects only the PK columns and bypasses the cache —
44
+ * these single-use sweep pages should never pollute the local cache.
45
+ */
46
+ export async function pageEntityByFilter(opts) {
47
+ const { entity, filter, cursor, batchSize, contextUser, preferKeyset } = opts;
48
+ const pkName = entity.FirstPrimaryKey?.Name;
49
+ const useKeyset = preferKeyset && canUseKeyset(entity) && !!pkName;
50
+ const rv = new RunView();
51
+ const sharedParams = {
52
+ EntityName: entity.Name,
53
+ Fields: entity.PrimaryKeys.map((pk) => pk.Name),
54
+ ResultType: 'simple',
55
+ MaxRows: batchSize,
56
+ BypassCache: true,
57
+ ExtraFilter: filter,
58
+ };
59
+ const offset = cursor?.Offset ?? 0;
60
+ const result = useKeyset
61
+ ? await rv.RunView({
62
+ ...sharedParams,
63
+ OrderBy: pkName,
64
+ AfterKey: cursor?.Key != null ? CompositeKey.FromKeyValuePair(pkName, cursor.Key) : undefined,
65
+ }, contextUser)
66
+ : await rv.RunView({ ...sharedParams, StartRow: offset }, contextUser);
67
+ if (!result.Success) {
68
+ throw new Error(`Record set source failed paging '${entity.Name}': ${result.ErrorMessage}`);
69
+ }
70
+ const rows = (result.Results ?? []);
71
+ const records = rows.map((row) => ({
72
+ EntityID: entity.ID,
73
+ RecordID: serializeRecordId(entity, row),
74
+ Record: row,
75
+ }));
76
+ const exhausted = records.length < batchSize;
77
+ let nextCursor;
78
+ if (useKeyset) {
79
+ const lastValue = rows.length > 0 ? rows[rows.length - 1][pkName] : undefined;
80
+ nextCursor = { Key: lastValue != null ? String(lastValue) : cursor?.Key };
81
+ }
82
+ else {
83
+ nextCursor = { Offset: offset + records.length };
84
+ }
85
+ return { Records: records, NextCursor: nextCursor, Exhausted: exhausted, TotalRowCount: result.TotalRowCount };
86
+ }
87
+ //# sourceMappingURL=sourceUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceUtil.js","sourceRoot":"","sources":["../../src/sources/sourceUtil.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview User-View source — resolves a saved User View and yields its members (PKs only) in
3
+ * offset-paginated batches. A view may carry an arbitrary OrderBy/filter that defeats keyset
4
+ * pagination, so this source uses offset (StartRow) paging.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
8
+ import { IRecordSetSource, SourceDescriptor } from '../interfaces.js';
9
+ import { ProcessCursor, RecordBatch } from '../types.js';
10
+ /** A source backed by a saved User View. */
11
+ export declare class ViewSource implements IRecordSetSource {
12
+ private readonly viewID;
13
+ private entity?;
14
+ /** @param viewID - The `MJ: User Views` ID to iterate. */
15
+ constructor(viewID: string);
16
+ Describe(): SourceDescriptor;
17
+ private resolveEntity;
18
+ NextBatch(cursor: ProcessCursor | undefined, batchSize: number, contextUser: UserInfo, provider?: IMetadataProvider): Promise<RecordBatch>;
19
+ }
20
+ //# sourceMappingURL=viewSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewSource.d.ts","sourceRoot":"","sources":["../../src/sources/viewSource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,iBAAiB,EAAqB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAa,MAAM,UAAU,CAAC;AAGjE,4CAA4C;AAC5C,qBAAa,UAAW,YAAW,gBAAgB;IAInC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,MAAM,CAAC,CAAa;IAE5B,0DAA0D;gBAC7B,MAAM,EAAE,MAAM;IAEpC,QAAQ,IAAI,gBAAgB;YAIrB,aAAa;IAiBd,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;CA2B1J"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @fileoverview User-View source — resolves a saved User View and yields its members (PKs only) in
3
+ * offset-paginated batches. A view may carry an arbitrary OrderBy/filter that defeats keyset
4
+ * pagination, so this source uses offset (StartRow) paging.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ import { Metadata, RunView } from '@memberjunction/core';
8
+ import { serializeRecordId } from './sourceUtil.js';
9
+ /** A source backed by a saved User View. */
10
+ export class ViewSource {
11
+ /** @param viewID - The `MJ: User Views` ID to iterate. */
12
+ constructor(viewID) {
13
+ this.viewID = viewID;
14
+ }
15
+ Describe() {
16
+ return { SourceType: 'View', SourceID: this.viewID, EntityID: this.entity?.ID };
17
+ }
18
+ async resolveEntity(provider) {
19
+ if (this.entity) {
20
+ return this.entity;
21
+ }
22
+ const md = provider ?? Metadata.Provider;
23
+ const entityName = await RunView.GetEntityNameFromRunViewParams({ ViewID: this.viewID }, provider ?? null);
24
+ if (!entityName) {
25
+ throw new Error(`ViewSource: could not determine the entity for view '${this.viewID}'`);
26
+ }
27
+ const entity = md.EntityByName(entityName);
28
+ if (!entity) {
29
+ throw new Error(`ViewSource: entity '${entityName}' not found in metadata`);
30
+ }
31
+ this.entity = entity;
32
+ return entity;
33
+ }
34
+ async NextBatch(cursor, batchSize, contextUser, provider) {
35
+ const entity = await this.resolveEntity(provider);
36
+ const offset = cursor?.Offset ?? 0;
37
+ const rv = new RunView();
38
+ const result = await rv.RunView({
39
+ ViewID: this.viewID,
40
+ Fields: entity.PrimaryKeys.map((pk) => pk.Name),
41
+ ResultType: 'simple',
42
+ StartRow: offset,
43
+ MaxRows: batchSize,
44
+ }, contextUser);
45
+ if (!result.Success) {
46
+ throw new Error(`ViewSource: failed running view '${this.viewID}': ${result.ErrorMessage}`);
47
+ }
48
+ const rows = (result.Results ?? []);
49
+ const records = rows.map((row) => ({
50
+ EntityID: entity.ID,
51
+ RecordID: serializeRecordId(entity, row),
52
+ Record: row,
53
+ }));
54
+ return {
55
+ Records: records,
56
+ NextCursor: { Offset: offset + records.length },
57
+ Exhausted: records.length < batchSize,
58
+ TotalRowCount: result.TotalRowCount,
59
+ };
60
+ }
61
+ }
62
+ //# sourceMappingURL=viewSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewSource.js","sourceRoot":"","sources":["../../src/sources/viewSource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAiC,QAAQ,EAAE,OAAO,EAAY,MAAM,sBAAsB,CAAC;AAGlG,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,4CAA4C;AAC5C,MAAM,OAAO,UAAU;IAGnB,0DAA0D;IAC1D,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAExC,QAAQ;QACX,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC;IACpF,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,QAA4B;QACpD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,MAAM,EAAE,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,8BAA8B,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC;QAC3G,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,wDAAwD,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,uBAAuB,UAAU,yBAAyB,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,MAAiC,EAAE,SAAiB,EAAE,WAAqB,EAAE,QAA4B;QAC5H,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;YAC/C,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,SAAS;SACrB,EAAE,WAAW,CAAC,CAAC;QAChB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,MAAM,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAA8B,CAAC;QACjE,MAAM,OAAO,GAAgB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC5C,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC;YACxC,MAAM,EAAE,GAAG;SACd,CAAC,CAAC,CAAC;QACJ,OAAO;YACH,OAAO,EAAE,OAAO;YAChB,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE;YAC/C,SAAS,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS;YACrC,aAAa,EAAE,MAAM,CAAC,aAAa;SACtC,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @fileoverview Core data types for the Record Set Processor substrate — the shapes shared between
3
+ * the source/processor/tracker seams and the engine. These types are pure data (no behavior) and
4
+ * carry no server-only dependencies, so they are safe to import on the client.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ /** A reference to a single record to be processed. */
8
+ export interface RecordRef {
9
+ /** ID of the entity this record belongs to. */
10
+ EntityID: string;
11
+ /** The record's primary key, serialized to a composite-key-safe string. */
12
+ RecordID: string;
13
+ /** Optional already-loaded record data (a plain row or a `BaseEntity`), to save a re-fetch. */
14
+ Record?: unknown;
15
+ }
16
+ /**
17
+ * Opaque resume cursor round-tripped between a source and the run tracker. A source populates
18
+ * exactly one of these depending on how it paginates; the engine never interprets it.
19
+ */
20
+ export interface ProcessCursor {
21
+ /** Offset (StartRow) for offset-paginated sources. */
22
+ Offset?: number;
23
+ /** Last-seen key for keyset (seek) paginated sources — the single-PK value as a string. */
24
+ Key?: string;
25
+ }
26
+ /** One page of records returned by a source, plus the cursor to fetch the next page. */
27
+ export interface RecordBatch {
28
+ /** The records in this batch (empty when the source is exhausted). */
29
+ Records: RecordRef[];
30
+ /** Cursor to pass to the next `NextBatch()` call. */
31
+ NextCursor: ProcessCursor;
32
+ /** True when this is the final batch — no further records remain. */
33
+ Exhausted: boolean;
34
+ /** Total matching rows in the source, when the source knows it (e.g. from `RunView.TotalRowCount`). */
35
+ TotalRowCount?: number;
36
+ }
37
+ /** Lifecycle status of a process run. Mirrors the `MJ: Process Runs.Status` value list. */
38
+ export type ProcessRunStatusValue = 'Pending' | 'Running' | 'Paused' | 'Completed' | 'Failed' | 'Cancelled';
39
+ /** Per-record outcome status. Mirrors the `MJ: Process Run Details.Status` value list. */
40
+ export type RecordResultStatusValue = 'Succeeded' | 'Failed' | 'Skipped';
41
+ /** What triggered a run. Mirrors the `MJ: Process Runs.TriggeredBy` value list. */
42
+ export type TriggeredByValue = 'OnChange' | 'Schedule' | 'OnDemand' | 'Manual';
43
+ /** The kind of record-set source. Mirrors the `MJ: Process Runs.SourceType` value list. */
44
+ export type SourceTypeValue = 'View' | 'List' | 'Filter' | 'Array' | 'Keyset' | 'SingleRecord';
45
+ /** The outcome of processing a single record, returned by an {@link IRecordProcessor}. */
46
+ export interface RecordResult {
47
+ /** Whether the record succeeded, failed, or was skipped. */
48
+ Status: RecordResultStatusValue;
49
+ /** Structured output payload produced for the record (persisted as JSON on the detail row). */
50
+ ResultPayload?: unknown;
51
+ /** Error detail when `Status` is `Failed`. */
52
+ ErrorMessage?: string;
53
+ /** Processing duration in milliseconds (the engine fills this in if the processor does not). */
54
+ DurationMs?: number;
55
+ /** Number of attempts made for this record. */
56
+ AttemptCount?: number;
57
+ /** Deep-trace link to an Action Execution Log, when the work was an Action. */
58
+ ActionExecutionLogID?: string;
59
+ /** Deep-trace link to an AI Agent Run, when the work was an Agent. */
60
+ AIAgentRunID?: string;
61
+ /** Deep-trace link to an AI Prompt Run, when the work was an Infer-and-Write-Back. */
62
+ AIPromptRunID?: string;
63
+ }
64
+ /** Running tallies for a process run. */
65
+ export interface RunCounts {
66
+ /** Records handed to the processor so far. */
67
+ Processed: number;
68
+ /** Records that succeeded. */
69
+ Success: number;
70
+ /** Records that failed. */
71
+ Error: number;
72
+ /** Records that were skipped. */
73
+ Skipped: number;
74
+ }
75
+ /** Progress snapshot emitted to a run's `onProgress` callback. */
76
+ export interface ProgressInfo extends RunCounts {
77
+ /** Known total record count, or null when the total is not known up-front. */
78
+ Total: number | null;
79
+ /** The record currently being processed, when available. */
80
+ CurrentRecordID?: string;
81
+ }
82
+ /** Final (or interim) summary of a process run. */
83
+ export interface ProcessRunSummary extends RunCounts {
84
+ /** Terminal or current run status. */
85
+ Status: ProcessRunStatusValue;
86
+ /** Known total record count, or null. */
87
+ Total: number | null;
88
+ /** When the run started. */
89
+ StartTime?: Date;
90
+ /** When the run ended. */
91
+ EndTime?: Date;
92
+ /** Run-level error message when `Status` is `Failed`. */
93
+ ErrorMessage?: string;
94
+ }
95
+ /** Result returned by `RecordSetProcessor.Process()` — a run summary plus the persisted run ID. */
96
+ export interface ProcessRunResult extends ProcessRunSummary {
97
+ /** ID of the persisted `MJ: Process Runs` row, when a persisting tracker was used. */
98
+ ProcessRunID?: string;
99
+ }
100
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACtB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wFAAwF;AACxF,MAAM,WAAW,WAAW;IACxB,sEAAsE;IACtE,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,qDAAqD;IACrD,UAAU,EAAE,aAAa,CAAC;IAC1B,qEAAqE;IACrE,SAAS,EAAE,OAAO,CAAC;IACnB,uGAAuG;IACvG,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,2FAA2F;AAC3F,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE5G,0FAA0F;AAC1F,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzE,mFAAmF;AACnF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/E,2FAA2F;AAC3F,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,cAAc,CAAC;AAE/F,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IACzB,4DAA4D;IAC5D,MAAM,EAAE,uBAAuB,CAAC;IAChC,+FAA+F;IAC/F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACtB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC3C,8EAA8E;IAC9E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,mDAAmD;AACnD,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAChD,sCAAsC;IACtC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,yCAAyC;IACzC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mGAAmG;AACnG,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACvD,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Core data types for the Record Set Processor substrate — the shapes shared between
3
+ * the source/processor/tracker seams and the engine. These types are pure data (no behavior) and
4
+ * carry no server-only dependencies, so they are safe to import on the client.
5
+ * @module @memberjunction/record-set-processor-base
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,10 +1,32 @@
1
1
  {
2
2
  "name": "@memberjunction/record-set-processor-base",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @memberjunction/record-set-processor-base",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
3
+ "type": "module",
4
+ "version": "5.42.0",
5
+ "description": "MemberJunction: Record Set Processor Base - interfaces, types, and source adapters for batched, resumable record-set processing. Client-safe.",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "/dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc && tsc-alias -f",
13
+ "watch": "tsc --watch",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest"
16
+ },
17
+ "author": "MemberJunction.com",
18
+ "license": "ISC",
19
+ "dependencies": {
20
+ "@memberjunction/core": "5.42.0",
21
+ "@memberjunction/global": "5.42.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "24.10.11",
25
+ "typescript": "^5.9.3",
26
+ "vitest": "^3.1.1"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/MemberJunction/MJ"
31
+ }
10
32
  }