@allsourcedev/client 0.23.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.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @allsourcedev/client
2
+
3
+ TypeScript/JavaScript client for the [AllSource](https://all-source.xyz) event store API.
4
+
5
+ Talks to the AllSource **Query Service** (the public gateway), not Core directly.
6
+ Ships compiled ESM + CJS with `.d.ts` types. Runs on Node 18+ and Bun. Zero
7
+ runtime dependencies (uses the global `fetch`).
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @allsourcedev/client
13
+ # or
14
+ bun add @allsourcedev/client
15
+ # or
16
+ pnpm add @allsourcedev/client
17
+ ```
18
+
19
+ > **Why not a git install?** `@allsourcedev/client` lives in the `all-source`
20
+ > monorepo under `sdks/typescript`. Git installers can't pull a sub-directory of
21
+ > a monorepo — that's why `bun add github:…#workspace=@allsourcedev/client` and
22
+ > `#path:sdks/typescript` return 404. Install from the npm registry (above).
23
+
24
+ ## Authentication
25
+
26
+ AllSource uses API keys (signed JWTs). Get one from your dashboard at
27
+ [all-source.xyz](https://all-source.xyz) → **Settings → API Keys**. The key is
28
+ sent in the `X-API-Key` header; the SDK does this for you when you pass `apiKey`
29
+ to the constructor.
30
+
31
+ Store the key in an env var rather than hard-coding it:
32
+
33
+ ```typescript
34
+ import { AllSourceClient } from "@allsourcedev/client";
35
+
36
+ const client = new AllSourceClient({
37
+ baseUrl: "https://allsource-query.fly.dev", // your Query Service URL
38
+ apiKey: process.env.ALLSOURCE_API_KEY!,
39
+ });
40
+ ```
41
+
42
+ The tenant is taken from the key — there is no separate tenant argument.
43
+
44
+ ## Quick Start
45
+
46
+ ```typescript
47
+ import { AllSourceClient } from "@allsourcedev/client";
48
+
49
+ const client = new AllSourceClient({
50
+ baseUrl: "https://allsource-query.fly.dev",
51
+ apiKey: process.env.ALLSOURCE_API_KEY!,
52
+ });
53
+
54
+ // Ingest an event — returns the stored event
55
+ const event = await client.ingestEvent({
56
+ event_type: "user.signup",
57
+ entity_id: "user-abc-123",
58
+ payload: { email: "jane@example.com", plan: "pro" },
59
+ metadata: { source: "web", ip: "1.2.3.4" },
60
+ });
61
+ console.log("Ingested:", event.id);
62
+
63
+ // Query events back
64
+ const { events, count } = await client.queryEvents({
65
+ entity_id: "user-abc-123",
66
+ limit: 50,
67
+ });
68
+ console.log(`Found ${count} events`);
69
+
70
+ // Health check (unauthenticated)
71
+ const health = await client.getHealth();
72
+ console.log("Status:", health.status);
73
+ ```
74
+
75
+ ## API
76
+
77
+ ### `new AllSourceClient(config)`
78
+
79
+ | Option | Type | Required | Default | Description |
80
+ |------------------|------------|----------|---------|--------------------------------------|
81
+ | `baseUrl` | `string` | Yes | — | AllSource Query Service URL |
82
+ | `apiKey` | `string` | Yes | — | API key (sent as `X-API-Key`) |
83
+ | `timeout` | `number` | No | `30000` | Request timeout in milliseconds |
84
+ | `retry` | `object` | No | — | Retry/backoff overrides |
85
+ | `circuitBreaker` | `object` | No | — | Circuit-breaker overrides |
86
+ | `fetch` | `function` | No | global | Custom `fetch` implementation |
87
+
88
+ ### `client.ingestEvent(event)` → `Event`
89
+
90
+ Ingest a single event and return the stored event (`id`, `timestamp`, …).
91
+
92
+ ```typescript
93
+ const stored = await client.ingestEvent({
94
+ event_type: "order.placed",
95
+ entity_id: "order-456",
96
+ payload: { total: 99.99, currency: "USD" },
97
+ metadata: { source: "checkout" }, // optional, preserved
98
+ });
99
+ ```
100
+
101
+ ### `client.ingestBatch(events)` → `{ count, events }`
102
+
103
+ Ingest many events in one request.
104
+
105
+ ### `client.queryEvents(params?)` → `{ events, count }`
106
+
107
+ Query events with optional filters.
108
+
109
+ | Param | Type | Description |
110
+ |--------------|----------|-----------------------------------|
111
+ | `entity_id` | `string` | Filter by entity ID |
112
+ | `event_type` | `string` | Filter by event type |
113
+ | `limit` | `number` | Max events to return |
114
+ | `offset` | `number` | Number of events to skip |
115
+ | `since` | `string` | Start time, inclusive (ISO 8601) |
116
+ | `until` | `string` | End time, inclusive (ISO 8601) |
117
+
118
+ ### `client.queryAndFold(params, folder)` → `S | undefined`
119
+
120
+ Query events and fold them into a derived state with an `EventFolder<S>`.
121
+
122
+ ### `client.listProjections()` → `{ projections, total }`
123
+
124
+ List projections from Core.
125
+
126
+ ### Prime projections
127
+
128
+ `definePrimeProjection(entityType, fieldPolicies)`,
129
+ `projectNode(nodeId)`, `listPrimeProjections()`,
130
+ `nodeFieldProvenance(nodeId, field)` — declarative projections with per-field
131
+ merge policies and provenance.
132
+
133
+ ### `client.getHealth()` → `HealthResponse`
134
+
135
+ Service health. Unauthenticated.
136
+
137
+ ### Reliability
138
+
139
+ Every request goes through exponential-backoff retries (on 408/429/5xx and
140
+ network errors) and a circuit breaker. Both are configurable via the constructor.
141
+
142
+ ### Error handling
143
+
144
+ API errors throw `AllSourceError` with `status` and `body`:
145
+
146
+ ```typescript
147
+ import { AllSourceClient, AllSourceError } from "@allsourcedev/client";
148
+
149
+ try {
150
+ await client.ingestEvent({ /* … */ });
151
+ } catch (err) {
152
+ if (err instanceof AllSourceError) {
153
+ console.error(`API error ${err.status}:`, err.body);
154
+ if (err.isUnauthorized()) console.error("Check your API key.");
155
+ }
156
+ }
157
+ ```
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,19 @@
1
+ import { type CircuitBreakerConfig } from "./types";
2
+ export type CircuitState = "closed" | "open" | "half-open";
3
+ export declare class CircuitBreaker {
4
+ private readonly threshold;
5
+ private readonly recoveryTimeout;
6
+ private consecutiveFailures;
7
+ private lastFailureTime;
8
+ private currentState;
9
+ constructor(config?: Partial<CircuitBreakerConfig>);
10
+ /** Returns the current circuit state. */
11
+ get state(): CircuitState;
12
+ /** Check if a request is allowed. Throws CircuitOpenError if the circuit is open. */
13
+ check(): void;
14
+ /** Record a successful request. Resets the circuit to closed. */
15
+ recordSuccess(): void;
16
+ /** Record a failed request. Opens the circuit after threshold consecutive failures. */
17
+ recordFailure(): void;
18
+ }
19
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,oBAAoB,EAAoB,MAAM,SAAS,CAAC;AAEtE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAO3D,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,YAAY,CAA0B;gBAElC,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAKtD,yCAAyC;IACzC,IAAI,KAAK,IAAI,YAAY,CAQxB;IAED,qFAAqF;IACrF,KAAK,IAAI,IAAI;IAQb,iEAAiE;IACjE,aAAa,IAAI,IAAI;IAKrB,uFAAuF;IACvF,aAAa,IAAI,IAAI;CAOtB"}
@@ -0,0 +1,48 @@
1
+ import { type EventFolder } from "./fold";
2
+ import { type AllSourceConfig, type CreatedEvent, type HealthResponse, type IngestEventInput, type PrimeProjection, type PrimeProjectionAck, type PrimeProvenance, type PrimeSnapshot, type ProjectionsResponse, type QueryEventsParams, type QueryEventsResponse } from "./types";
3
+ export declare class AllSourceClient {
4
+ private readonly baseUrl;
5
+ private readonly apiKey;
6
+ private readonly timeout;
7
+ private readonly retryConfig;
8
+ private readonly circuitBreaker;
9
+ private readonly fetch;
10
+ constructor(config: AllSourceConfig);
11
+ /**
12
+ * Ingest a single event into AllSource Core.
13
+ *
14
+ * Returns the created event's `id`, `timestamp` and `version`. The gateway
15
+ * wraps the ack in a `{ data }` envelope and keys the id as `event_id`; this
16
+ * unwraps and normalizes it to `id`.
17
+ */
18
+ ingestEvent(event: IngestEventInput): Promise<CreatedEvent>;
19
+ /**
20
+ * Ingest a batch of events into AllSource Core.
21
+ *
22
+ * Returns how many were ingested and the created events
23
+ * (`id` / `timestamp` / `version`).
24
+ */
25
+ ingestBatch(events: IngestEventInput[]): Promise<{
26
+ count: number;
27
+ events: CreatedEvent[];
28
+ }>;
29
+ /** Query events with optional filters. */
30
+ queryEvents(params?: QueryEventsParams): Promise<QueryEventsResponse>;
31
+ /** List all projections from AllSource Core. */
32
+ listProjections(): Promise<ProjectionsResponse>;
33
+ /** List all Prime projection definitions from the gateway. */
34
+ listPrimeProjections(): Promise<PrimeProjection[]>;
35
+ /** Define (or update) a Prime projection with per-field merge policies. */
36
+ definePrimeProjection(entityType: string, fieldPolicies: Record<string, string>): Promise<PrimeProjectionAck>;
37
+ /** Project a Prime node into a materialized snapshot. */
38
+ projectNode(nodeId: string): Promise<PrimeSnapshot>;
39
+ /** Fetch provenance for a single field on a Prime node. Throws AllSourceError (404) when none. */
40
+ nodeFieldProvenance(nodeId: string, field: string): Promise<PrimeProvenance>;
41
+ /** Query events and fold them into a state using the provided folder. */
42
+ queryAndFold<S>(params: QueryEventsParams, folder: EventFolder<S>): Promise<S | undefined>;
43
+ /** Check the health of the AllSource service. */
44
+ getHealth(): Promise<HealthResponse>;
45
+ private request;
46
+ private computeDelay;
47
+ }
48
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,QAAQ,CAAC;AACtD,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,YAAY,EAEjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAEzB,MAAM,SAAS,CAAC;AA6BjB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;gBAEpC,MAAM,EAAE,eAAe;IAmBnC;;;;;;OAMG;IACG,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IASjE;;;;;OAKG;IACG,WAAW,CACf,MAAM,EAAE,gBAAgB,EAAE,GACzB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IASrD,0CAA0C;IACpC,WAAW,CACf,MAAM,GAAE,iBAAsB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;IAc/B,gDAAgD;IAC1C,eAAe,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIrD,8DAA8D;IACxD,oBAAoB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAQxD,2EAA2E;IACrE,qBAAqB,CACzB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,OAAO,CAAC,kBAAkB,CAAC;IAS9B,yDAAyD;IACnD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAQzD,kGAAkG;IAC5F,mBAAmB,CACvB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,CAAC;IAQ3B,yEAAyE;IACnE,YAAY,CAAC,CAAC,EAClB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAKzB,iDAAiD;IAC3C,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;YAI5B,OAAO;IAmGrB,OAAO,CAAC,YAAY;CAQrB"}
package/dist/fold.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { Event } from "./types";
2
+ /** Interface for folding events into a state. */
3
+ export interface EventFolder<S> {
4
+ /** Apply an event to the folder's internal state. Returns true if the event was relevant. */
5
+ apply(event: Event): boolean;
6
+ /** Finalize and return the accumulated state. Returns undefined if no relevant events were applied. */
7
+ finalize(): S | undefined;
8
+ }
9
+ /** Fold a sequence of events using the given folder. */
10
+ export declare function foldEvents<S>(folder: EventFolder<S>, events: Event[]): S | undefined;
11
+ //# sourceMappingURL=fold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,iDAAiD;AACjD,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,6FAA6F;IAC7F,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;IAC7B,uGAAuG;IACvG,QAAQ,IAAI,CAAC,GAAG,SAAS,CAAC;CAC3B;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,SAAS,CAKpF"}
package/dist/index.cjs ADDED
@@ -0,0 +1,297 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/index.ts
30
+ var exports_src = {};
31
+ __export(exports_src, {
32
+ foldEvents: () => foldEvents,
33
+ CircuitOpenError: () => CircuitOpenError,
34
+ CircuitBreaker: () => CircuitBreaker,
35
+ AllSourceError: () => AllSourceError,
36
+ AllSourceClient: () => AllSourceClient
37
+ });
38
+ module.exports = __toCommonJS(exports_src);
39
+
40
+ // src/types.ts
41
+ class AllSourceError extends Error {
42
+ status;
43
+ body;
44
+ constructor(message, status, body) {
45
+ super(message);
46
+ this.status = status;
47
+ this.body = body;
48
+ this.name = "AllSourceError";
49
+ }
50
+ isUnauthorized() {
51
+ return this.status === 401;
52
+ }
53
+ isRateLimited() {
54
+ return this.status === 429;
55
+ }
56
+ isNotFound() {
57
+ return this.status === 404;
58
+ }
59
+ isForbidden() {
60
+ return this.status === 403;
61
+ }
62
+ isServerError() {
63
+ return this.status >= 500;
64
+ }
65
+ isRetryable() {
66
+ return [408, 429, 500, 502, 503, 504].includes(this.status);
67
+ }
68
+ }
69
+
70
+ class CircuitOpenError extends Error {
71
+ constructor(message = "Circuit breaker is open") {
72
+ super(message);
73
+ this.name = "CircuitOpenError";
74
+ }
75
+ }
76
+
77
+ // src/circuit-breaker.ts
78
+ var DEFAULT_CONFIG = {
79
+ threshold: 5,
80
+ recoveryTimeout: 30000
81
+ };
82
+
83
+ class CircuitBreaker {
84
+ threshold;
85
+ recoveryTimeout;
86
+ consecutiveFailures = 0;
87
+ lastFailureTime = 0;
88
+ currentState = "closed";
89
+ constructor(config = {}) {
90
+ this.threshold = config.threshold ?? DEFAULT_CONFIG.threshold;
91
+ this.recoveryTimeout = config.recoveryTimeout ?? DEFAULT_CONFIG.recoveryTimeout;
92
+ }
93
+ get state() {
94
+ if (this.currentState === "open") {
95
+ const elapsed = Date.now() - this.lastFailureTime;
96
+ if (elapsed >= this.recoveryTimeout) {
97
+ return "half-open";
98
+ }
99
+ }
100
+ return this.currentState;
101
+ }
102
+ check() {
103
+ const s = this.state;
104
+ if (s === "open") {
105
+ throw new CircuitOpenError;
106
+ }
107
+ }
108
+ recordSuccess() {
109
+ this.consecutiveFailures = 0;
110
+ this.currentState = "closed";
111
+ }
112
+ recordFailure() {
113
+ this.consecutiveFailures++;
114
+ this.lastFailureTime = Date.now();
115
+ if (this.consecutiveFailures >= this.threshold) {
116
+ this.currentState = "open";
117
+ }
118
+ }
119
+ }
120
+
121
+ // src/fold.ts
122
+ function foldEvents(folder, events) {
123
+ for (const event of events) {
124
+ folder.apply(event);
125
+ }
126
+ return folder.finalize();
127
+ }
128
+
129
+ // src/client.ts
130
+ var DEFAULT_TIMEOUT = 30000;
131
+ var DEFAULT_RETRY = {
132
+ maxRetries: 3,
133
+ baseDelay: 200,
134
+ backoffFactor: 2,
135
+ maxDelay: 1e4
136
+ };
137
+ var RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504]);
138
+ function normalizeCreated(raw) {
139
+ return {
140
+ id: raw.event_id ?? raw.id ?? "",
141
+ timestamp: raw.timestamp,
142
+ version: raw.version
143
+ };
144
+ }
145
+
146
+ class AllSourceClient {
147
+ baseUrl;
148
+ apiKey;
149
+ timeout;
150
+ retryConfig;
151
+ circuitBreaker;
152
+ fetch;
153
+ constructor(config) {
154
+ if (!config.baseUrl)
155
+ throw new Error("baseUrl is required");
156
+ if (!config.apiKey)
157
+ throw new Error("apiKey is required");
158
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
159
+ this.apiKey = config.apiKey;
160
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
161
+ this.retryConfig = {
162
+ maxRetries: config.retry?.maxRetries ?? DEFAULT_RETRY.maxRetries,
163
+ baseDelay: config.retry?.baseDelay ?? DEFAULT_RETRY.baseDelay,
164
+ backoffFactor: config.retry?.backoffFactor ?? DEFAULT_RETRY.backoffFactor,
165
+ maxDelay: config.retry?.maxDelay ?? DEFAULT_RETRY.maxDelay
166
+ };
167
+ this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
168
+ this.fetch = config.fetch ?? globalThis.fetch;
169
+ }
170
+ async ingestEvent(event) {
171
+ const res = await this.request("POST", "/api/v1/events", event);
172
+ return normalizeCreated(res.data);
173
+ }
174
+ async ingestBatch(events) {
175
+ const res = await this.request("POST", "/api/v1/events/batch", { events });
176
+ return { count: res.count, events: (res.data ?? []).map(normalizeCreated) };
177
+ }
178
+ async queryEvents(params = {}) {
179
+ const query = new URLSearchParams;
180
+ for (const [key, value] of Object.entries(params)) {
181
+ if (value !== undefined && value !== null) {
182
+ query.set(key, String(value));
183
+ }
184
+ }
185
+ const qs = query.toString();
186
+ const path = qs ? `/api/v1/events/query?${qs}` : "/api/v1/events/query";
187
+ return this.request("GET", path);
188
+ }
189
+ async listProjections() {
190
+ return this.request("GET", "/api/v1/projections");
191
+ }
192
+ async listPrimeProjections() {
193
+ const res = await this.request("GET", "/api/v1/prime/projections");
194
+ return res.data;
195
+ }
196
+ async definePrimeProjection(entityType, fieldPolicies) {
197
+ const res = await this.request("POST", "/api/v1/prime/projections", { entity_type: entityType, field_policies: fieldPolicies });
198
+ return res.data;
199
+ }
200
+ async projectNode(nodeId) {
201
+ const res = await this.request("POST", `/api/v1/prime/nodes/${nodeId}/project`);
202
+ return res.data;
203
+ }
204
+ async nodeFieldProvenance(nodeId, field) {
205
+ const res = await this.request("GET", `/api/v1/prime/nodes/${nodeId}/fields/${field}/provenance`);
206
+ return res.data;
207
+ }
208
+ async queryAndFold(params, folder) {
209
+ const result = await this.queryEvents(params);
210
+ return foldEvents(folder, result.events);
211
+ }
212
+ async getHealth() {
213
+ return this.request("GET", "/health");
214
+ }
215
+ async request(method, path, body) {
216
+ this.circuitBreaker.check();
217
+ const url = `${this.baseUrl}${path}`;
218
+ const headers = {
219
+ "X-API-Key": this.apiKey,
220
+ Accept: "application/json"
221
+ };
222
+ if (body !== undefined) {
223
+ headers["Content-Type"] = "application/json";
224
+ }
225
+ let lastError;
226
+ const maxAttempts = this.retryConfig.maxRetries + 1;
227
+ for (let attempt = 0;attempt < maxAttempts; attempt++) {
228
+ if (attempt > 0) {
229
+ const delay = this.computeDelay(attempt);
230
+ await new Promise((r) => setTimeout(r, delay));
231
+ }
232
+ const controller = new AbortController;
233
+ const timer = setTimeout(() => controller.abort(), this.timeout);
234
+ try {
235
+ const response = await this.fetch(url, {
236
+ method,
237
+ headers,
238
+ body: body !== undefined ? JSON.stringify(body) : undefined,
239
+ signal: controller.signal
240
+ });
241
+ if (!response.ok) {
242
+ const text = await response.text();
243
+ let responseBody;
244
+ try {
245
+ responseBody = JSON.parse(text);
246
+ } catch {
247
+ responseBody = text;
248
+ }
249
+ const error = new AllSourceError(`AllSource API error: ${response.status} ${response.statusText}`, response.status, responseBody);
250
+ if (RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxAttempts - 1) {
251
+ lastError = error;
252
+ continue;
253
+ }
254
+ this.circuitBreaker.recordFailure();
255
+ throw error;
256
+ }
257
+ this.circuitBreaker.recordSuccess();
258
+ return await response.json();
259
+ } catch (error) {
260
+ if (error instanceof AllSourceError) {
261
+ if (error.isRetryable() && attempt < maxAttempts - 1) {
262
+ lastError = error;
263
+ continue;
264
+ }
265
+ this.circuitBreaker.recordFailure();
266
+ throw error;
267
+ }
268
+ if (error instanceof DOMException && error.name === "AbortError") {
269
+ const timeoutErr = new AllSourceError(`Request timeout after ${this.timeout}ms`, 0);
270
+ if (attempt < maxAttempts - 1) {
271
+ lastError = timeoutErr;
272
+ continue;
273
+ }
274
+ this.circuitBreaker.recordFailure();
275
+ throw timeoutErr;
276
+ }
277
+ if (attempt < maxAttempts - 1) {
278
+ lastError = error;
279
+ continue;
280
+ }
281
+ this.circuitBreaker.recordFailure();
282
+ throw error;
283
+ } finally {
284
+ clearTimeout(timer);
285
+ }
286
+ }
287
+ this.circuitBreaker.recordFailure();
288
+ throw lastError;
289
+ }
290
+ computeDelay(attempt) {
291
+ const { baseDelay, backoffFactor, maxDelay } = this.retryConfig;
292
+ const exponentialDelay = baseDelay * Math.pow(backoffFactor, attempt - 1);
293
+ const capped = Math.min(exponentialDelay, maxDelay);
294
+ const jitter = Math.random() * capped;
295
+ return Math.floor(jitter);
296
+ }
297
+ }
@@ -0,0 +1,7 @@
1
+ export { AllSourceClient } from "./client";
2
+ export { CircuitBreaker } from "./circuit-breaker";
3
+ export type { CircuitState } from "./circuit-breaker";
4
+ export { foldEvents } from "./fold";
5
+ export type { EventFolder } from "./fold";
6
+ export { AllSourceError, CircuitOpenError, type AllSourceConfig, type CircuitBreakerConfig, type CreatedEvent, type Event, type HealthResponse, type IngestEventInput, type PrimeProjection, type PrimeProjectionAck, type PrimeProvenance, type PrimeSnapshot, type Projection, type ProjectionsResponse, type QueryEventsParams, type QueryEventsResponse, type RetryConfig, } from "./types";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,SAAS,CAAC"}
package/dist/index.mjs ADDED
@@ -0,0 +1,265 @@
1
+ // src/types.ts
2
+ class AllSourceError extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.status = status;
8
+ this.body = body;
9
+ this.name = "AllSourceError";
10
+ }
11
+ isUnauthorized() {
12
+ return this.status === 401;
13
+ }
14
+ isRateLimited() {
15
+ return this.status === 429;
16
+ }
17
+ isNotFound() {
18
+ return this.status === 404;
19
+ }
20
+ isForbidden() {
21
+ return this.status === 403;
22
+ }
23
+ isServerError() {
24
+ return this.status >= 500;
25
+ }
26
+ isRetryable() {
27
+ return [408, 429, 500, 502, 503, 504].includes(this.status);
28
+ }
29
+ }
30
+
31
+ class CircuitOpenError extends Error {
32
+ constructor(message = "Circuit breaker is open") {
33
+ super(message);
34
+ this.name = "CircuitOpenError";
35
+ }
36
+ }
37
+
38
+ // src/circuit-breaker.ts
39
+ var DEFAULT_CONFIG = {
40
+ threshold: 5,
41
+ recoveryTimeout: 30000
42
+ };
43
+
44
+ class CircuitBreaker {
45
+ threshold;
46
+ recoveryTimeout;
47
+ consecutiveFailures = 0;
48
+ lastFailureTime = 0;
49
+ currentState = "closed";
50
+ constructor(config = {}) {
51
+ this.threshold = config.threshold ?? DEFAULT_CONFIG.threshold;
52
+ this.recoveryTimeout = config.recoveryTimeout ?? DEFAULT_CONFIG.recoveryTimeout;
53
+ }
54
+ get state() {
55
+ if (this.currentState === "open") {
56
+ const elapsed = Date.now() - this.lastFailureTime;
57
+ if (elapsed >= this.recoveryTimeout) {
58
+ return "half-open";
59
+ }
60
+ }
61
+ return this.currentState;
62
+ }
63
+ check() {
64
+ const s = this.state;
65
+ if (s === "open") {
66
+ throw new CircuitOpenError;
67
+ }
68
+ }
69
+ recordSuccess() {
70
+ this.consecutiveFailures = 0;
71
+ this.currentState = "closed";
72
+ }
73
+ recordFailure() {
74
+ this.consecutiveFailures++;
75
+ this.lastFailureTime = Date.now();
76
+ if (this.consecutiveFailures >= this.threshold) {
77
+ this.currentState = "open";
78
+ }
79
+ }
80
+ }
81
+
82
+ // src/fold.ts
83
+ function foldEvents(folder, events) {
84
+ for (const event of events) {
85
+ folder.apply(event);
86
+ }
87
+ return folder.finalize();
88
+ }
89
+
90
+ // src/client.ts
91
+ var DEFAULT_TIMEOUT = 30000;
92
+ var DEFAULT_RETRY = {
93
+ maxRetries: 3,
94
+ baseDelay: 200,
95
+ backoffFactor: 2,
96
+ maxDelay: 1e4
97
+ };
98
+ var RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504]);
99
+ function normalizeCreated(raw) {
100
+ return {
101
+ id: raw.event_id ?? raw.id ?? "",
102
+ timestamp: raw.timestamp,
103
+ version: raw.version
104
+ };
105
+ }
106
+
107
+ class AllSourceClient {
108
+ baseUrl;
109
+ apiKey;
110
+ timeout;
111
+ retryConfig;
112
+ circuitBreaker;
113
+ fetch;
114
+ constructor(config) {
115
+ if (!config.baseUrl)
116
+ throw new Error("baseUrl is required");
117
+ if (!config.apiKey)
118
+ throw new Error("apiKey is required");
119
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
120
+ this.apiKey = config.apiKey;
121
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
122
+ this.retryConfig = {
123
+ maxRetries: config.retry?.maxRetries ?? DEFAULT_RETRY.maxRetries,
124
+ baseDelay: config.retry?.baseDelay ?? DEFAULT_RETRY.baseDelay,
125
+ backoffFactor: config.retry?.backoffFactor ?? DEFAULT_RETRY.backoffFactor,
126
+ maxDelay: config.retry?.maxDelay ?? DEFAULT_RETRY.maxDelay
127
+ };
128
+ this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
129
+ this.fetch = config.fetch ?? globalThis.fetch;
130
+ }
131
+ async ingestEvent(event) {
132
+ const res = await this.request("POST", "/api/v1/events", event);
133
+ return normalizeCreated(res.data);
134
+ }
135
+ async ingestBatch(events) {
136
+ const res = await this.request("POST", "/api/v1/events/batch", { events });
137
+ return { count: res.count, events: (res.data ?? []).map(normalizeCreated) };
138
+ }
139
+ async queryEvents(params = {}) {
140
+ const query = new URLSearchParams;
141
+ for (const [key, value] of Object.entries(params)) {
142
+ if (value !== undefined && value !== null) {
143
+ query.set(key, String(value));
144
+ }
145
+ }
146
+ const qs = query.toString();
147
+ const path = qs ? `/api/v1/events/query?${qs}` : "/api/v1/events/query";
148
+ return this.request("GET", path);
149
+ }
150
+ async listProjections() {
151
+ return this.request("GET", "/api/v1/projections");
152
+ }
153
+ async listPrimeProjections() {
154
+ const res = await this.request("GET", "/api/v1/prime/projections");
155
+ return res.data;
156
+ }
157
+ async definePrimeProjection(entityType, fieldPolicies) {
158
+ const res = await this.request("POST", "/api/v1/prime/projections", { entity_type: entityType, field_policies: fieldPolicies });
159
+ return res.data;
160
+ }
161
+ async projectNode(nodeId) {
162
+ const res = await this.request("POST", `/api/v1/prime/nodes/${nodeId}/project`);
163
+ return res.data;
164
+ }
165
+ async nodeFieldProvenance(nodeId, field) {
166
+ const res = await this.request("GET", `/api/v1/prime/nodes/${nodeId}/fields/${field}/provenance`);
167
+ return res.data;
168
+ }
169
+ async queryAndFold(params, folder) {
170
+ const result = await this.queryEvents(params);
171
+ return foldEvents(folder, result.events);
172
+ }
173
+ async getHealth() {
174
+ return this.request("GET", "/health");
175
+ }
176
+ async request(method, path, body) {
177
+ this.circuitBreaker.check();
178
+ const url = `${this.baseUrl}${path}`;
179
+ const headers = {
180
+ "X-API-Key": this.apiKey,
181
+ Accept: "application/json"
182
+ };
183
+ if (body !== undefined) {
184
+ headers["Content-Type"] = "application/json";
185
+ }
186
+ let lastError;
187
+ const maxAttempts = this.retryConfig.maxRetries + 1;
188
+ for (let attempt = 0;attempt < maxAttempts; attempt++) {
189
+ if (attempt > 0) {
190
+ const delay = this.computeDelay(attempt);
191
+ await new Promise((r) => setTimeout(r, delay));
192
+ }
193
+ const controller = new AbortController;
194
+ const timer = setTimeout(() => controller.abort(), this.timeout);
195
+ try {
196
+ const response = await this.fetch(url, {
197
+ method,
198
+ headers,
199
+ body: body !== undefined ? JSON.stringify(body) : undefined,
200
+ signal: controller.signal
201
+ });
202
+ if (!response.ok) {
203
+ const text = await response.text();
204
+ let responseBody;
205
+ try {
206
+ responseBody = JSON.parse(text);
207
+ } catch {
208
+ responseBody = text;
209
+ }
210
+ const error = new AllSourceError(`AllSource API error: ${response.status} ${response.statusText}`, response.status, responseBody);
211
+ if (RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxAttempts - 1) {
212
+ lastError = error;
213
+ continue;
214
+ }
215
+ this.circuitBreaker.recordFailure();
216
+ throw error;
217
+ }
218
+ this.circuitBreaker.recordSuccess();
219
+ return await response.json();
220
+ } catch (error) {
221
+ if (error instanceof AllSourceError) {
222
+ if (error.isRetryable() && attempt < maxAttempts - 1) {
223
+ lastError = error;
224
+ continue;
225
+ }
226
+ this.circuitBreaker.recordFailure();
227
+ throw error;
228
+ }
229
+ if (error instanceof DOMException && error.name === "AbortError") {
230
+ const timeoutErr = new AllSourceError(`Request timeout after ${this.timeout}ms`, 0);
231
+ if (attempt < maxAttempts - 1) {
232
+ lastError = timeoutErr;
233
+ continue;
234
+ }
235
+ this.circuitBreaker.recordFailure();
236
+ throw timeoutErr;
237
+ }
238
+ if (attempt < maxAttempts - 1) {
239
+ lastError = error;
240
+ continue;
241
+ }
242
+ this.circuitBreaker.recordFailure();
243
+ throw error;
244
+ } finally {
245
+ clearTimeout(timer);
246
+ }
247
+ }
248
+ this.circuitBreaker.recordFailure();
249
+ throw lastError;
250
+ }
251
+ computeDelay(attempt) {
252
+ const { baseDelay, backoffFactor, maxDelay } = this.retryConfig;
253
+ const exponentialDelay = baseDelay * Math.pow(backoffFactor, attempt - 1);
254
+ const capped = Math.min(exponentialDelay, maxDelay);
255
+ const jitter = Math.random() * capped;
256
+ return Math.floor(jitter);
257
+ }
258
+ }
259
+ export {
260
+ foldEvents,
261
+ CircuitOpenError,
262
+ CircuitBreaker,
263
+ AllSourceError,
264
+ AllSourceClient
265
+ };
@@ -0,0 +1,152 @@
1
+ /** Retry configuration with exponential backoff. */
2
+ export interface RetryConfig {
3
+ /** Maximum number of retries. Defaults to 3. */
4
+ maxRetries: number;
5
+ /** Base delay in milliseconds. Defaults to 200. */
6
+ baseDelay: number;
7
+ /** Backoff multiplier. Defaults to 2.0. */
8
+ backoffFactor: number;
9
+ /** Maximum delay in milliseconds. Defaults to 10000. */
10
+ maxDelay: number;
11
+ }
12
+ /** Circuit breaker configuration. */
13
+ export interface CircuitBreakerConfig {
14
+ /** Number of consecutive failures before opening the circuit. Defaults to 5. */
15
+ threshold: number;
16
+ /** Milliseconds to wait before entering half-open state. Defaults to 30000. */
17
+ recoveryTimeout: number;
18
+ }
19
+ /** Configuration options for the AllSource client. */
20
+ export interface AllSourceConfig {
21
+ /** Base URL of the AllSource Query Service (e.g., "https://allsource-query.fly.dev"). */
22
+ baseUrl: string;
23
+ /** API key for authentication (sent as X-API-Key header). */
24
+ apiKey: string;
25
+ /** Request timeout in milliseconds. Defaults to 30000. */
26
+ timeout?: number;
27
+ /** Retry configuration. Uses sensible defaults if omitted. */
28
+ retry?: Partial<RetryConfig>;
29
+ /** Circuit breaker configuration. Uses sensible defaults if omitted. */
30
+ circuitBreaker?: Partial<CircuitBreakerConfig>;
31
+ /** Custom fetch function. Defaults to globalThis.fetch. */
32
+ fetch?: typeof globalThis.fetch;
33
+ }
34
+ /** An event to ingest into AllSource. */
35
+ export interface IngestEventInput {
36
+ /** The type of event (e.g., "user.signup", "order.placed"). */
37
+ event_type: string;
38
+ /** The entity this event belongs to (e.g., user ID, order ID). */
39
+ entity_id: string;
40
+ /** Arbitrary JSON payload for the event. */
41
+ payload: Record<string, unknown>;
42
+ /** Optional metadata (e.g., source, version, ip). */
43
+ metadata?: Record<string, unknown>;
44
+ }
45
+ /** A stored event returned from AllSource. */
46
+ export interface Event {
47
+ id: string;
48
+ event_type: string;
49
+ entity_id: string;
50
+ payload: Record<string, unknown>;
51
+ metadata: Record<string, unknown>;
52
+ timestamp: string;
53
+ stream_id?: string;
54
+ version?: number;
55
+ tenant_id?: string;
56
+ }
57
+ /**
58
+ * Acknowledgement for a created event, returned by `ingestEvent` and (per item)
59
+ * `ingestBatch`. The gateway keys the id as `event_id`; the SDK normalizes it
60
+ * to `id` for parity with queried events.
61
+ */
62
+ export interface CreatedEvent {
63
+ /** The stored event's id. */
64
+ id: string;
65
+ /** Server-assigned timestamp (ISO 8601). */
66
+ timestamp: string;
67
+ /** Monotonic version assigned by Core, when provided. */
68
+ version?: number;
69
+ }
70
+ /** Query parameters for filtering events. */
71
+ export interface QueryEventsParams {
72
+ /** Filter by entity ID. */
73
+ entity_id?: string;
74
+ /** Filter by event type. */
75
+ event_type?: string;
76
+ /** Maximum number of events to return. */
77
+ limit?: number;
78
+ /** Number of events to skip. */
79
+ offset?: number;
80
+ /** Start time filter (ISO 8601). */
81
+ since?: string;
82
+ /** End time filter (ISO 8601). */
83
+ until?: string;
84
+ }
85
+ /** Response from querying events. */
86
+ export interface QueryEventsResponse {
87
+ events: Event[];
88
+ count: number;
89
+ }
90
+ /** A projection returned from AllSource Core. */
91
+ export interface Projection {
92
+ name: string;
93
+ state?: unknown;
94
+ [key: string]: unknown;
95
+ }
96
+ /** Response from listing projections. */
97
+ export interface ProjectionsResponse {
98
+ projections: Projection[];
99
+ total: number;
100
+ }
101
+ /** A Prime projection definition (entity type plus per-field merge policies). */
102
+ export interface PrimeProjection {
103
+ entity_type: string;
104
+ field_policies: Record<string, string>;
105
+ }
106
+ /** Acknowledgement returned when defining a Prime projection. */
107
+ export interface PrimeProjectionAck {
108
+ entity_type: string;
109
+ persisted: boolean;
110
+ }
111
+ /** A materialized Prime node snapshot. */
112
+ export interface PrimeSnapshot {
113
+ entity_type: string;
114
+ fields: Record<string, unknown>;
115
+ observation_count: number;
116
+ }
117
+ /** Provenance for a single field on a Prime node. */
118
+ export interface PrimeProvenance {
119
+ field: string;
120
+ value: unknown;
121
+ source_event_id: string;
122
+ source_event_at: string;
123
+ merge_policy_applied: string;
124
+ }
125
+ /** Response from the health endpoint. */
126
+ export interface HealthResponse {
127
+ status: string;
128
+ [key: string]: unknown;
129
+ }
130
+ /** Error thrown by the AllSource client. */
131
+ export declare class AllSourceError extends Error {
132
+ readonly status: number;
133
+ readonly body?: unknown | undefined;
134
+ constructor(message: string, status: number, body?: unknown | undefined);
135
+ /** Whether the error is a 401 Unauthorized. */
136
+ isUnauthorized(): boolean;
137
+ /** Whether the error is a 429 Rate Limited. */
138
+ isRateLimited(): boolean;
139
+ /** Whether the error is a 404 Not Found. */
140
+ isNotFound(): boolean;
141
+ /** Whether the error is a 403 Forbidden. */
142
+ isForbidden(): boolean;
143
+ /** Whether the error is a server error (5xx). */
144
+ isServerError(): boolean;
145
+ /** Whether the error is retryable (408, 429, 500, 502, 503, 504). */
146
+ isRetryable(): boolean;
147
+ }
148
+ /** Error thrown when the circuit breaker is open. */
149
+ export declare class CircuitOpenError extends Error {
150
+ constructor(message?: string);
151
+ }
152
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@allsourcedev/client",
3
+ "version": "0.23.0",
4
+ "description": "JavaScript/TypeScript client for the AllSource event store API",
5
+ "license": "MIT",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "bun build src/index.ts --outfile dist/index.mjs --target node --format esm && bun build src/index.ts --outfile dist/index.cjs --target node --format cjs && bun run build:types",
22
+ "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
23
+ "type-check": "tsc --noEmit",
24
+ "test": "bun test",
25
+ "smoke": "bun run scripts/smoke.ts",
26
+ "clean": "rm -rf dist .turbo",
27
+ "prepublishOnly": "bun run build"
28
+ },
29
+ "devDependencies": {
30
+ "@types/bun": "^1.1.13",
31
+ "typescript": "^6.0.2"
32
+ },
33
+ "keywords": [
34
+ "allsource",
35
+ "event-store",
36
+ "event-sourcing",
37
+ "typescript",
38
+ "api-client"
39
+ ],
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/all-source-os/all-source",
43
+ "directory": "sdks/typescript"
44
+ }
45
+ }