@secondlayer/sdk 0.10.3 → 1.0.1

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 CHANGED
@@ -19,27 +19,6 @@ const sl = new SecondLayer({
19
19
  });
20
20
  ```
21
21
 
22
- ## Streams
23
-
24
- Manage real-time event streams with endpoint delivery.
25
-
26
- ```typescript
27
- // Create
28
- const { stream, signingSecret } = await sl.streams.create({
29
- name: "my-stream",
30
- endpointUrl: "https://example.com/receive",
31
- filters: { type: "contract_call", contract_id: "SP...token" },
32
- });
33
-
34
- // List
35
- const { streams, total } = await sl.streams.list({ status: "active" });
36
-
37
- // Get / Update / Delete
38
- const stream = await sl.streams.get("stream-id");
39
- await sl.streams.update("stream-id", { name: "renamed" });
40
- await sl.streams.delete("stream-id");
41
- ```
42
-
43
22
  ## Subgraphs
44
23
 
45
24
  Deploy and query subgraphs (custom indexers).
@@ -101,7 +80,7 @@ const run = await sl.workflows.getRun("run-id");
101
80
  import { ApiError } from "@secondlayer/sdk";
102
81
 
103
82
  try {
104
- await sl.streams.get("nonexistent");
83
+ await sl.subgraphs.get("nonexistent");
105
84
  } catch (err) {
106
85
  if (err instanceof ApiError) {
107
86
  console.log(err.status); // 404
package/dist/index.d.ts CHANGED
@@ -4,10 +4,13 @@ interface SecondLayerOptions {
4
4
  baseUrl: string;
5
5
  /** Bearer token for authenticated requests. */
6
6
  apiKey?: string;
7
+ /** Deploy origin label sent as `x-sl-origin` (telemetry). Defaults to `cli`. */
8
+ origin?: "cli" | "mcp" | "session";
7
9
  }
8
10
  declare abstract class BaseClient {
9
11
  protected baseUrl: string;
10
12
  protected apiKey?: string;
13
+ protected origin: "cli" | "mcp" | "session";
11
14
  constructor(options?: Partial<SecondLayerOptions>);
12
15
  static authHeaders(apiKey?: string): Record<string, string>;
13
16
  protected request<T>(method: string, path: string, body?: unknown): Promise<T>;
@@ -45,52 +48,28 @@ declare class Marketplace extends BaseClient {
45
48
  }
46
49
  }>;
47
50
  }
48
- import { BulkPauseResponse, BulkResumeResponse, CreateStream, CreateStreamResponse, ListStreamsResponse, StreamResponse, UpdateStream } from "@secondlayer/shared/schemas";
49
- interface DeliverySummary {
50
- id: string;
51
- blockHeight: number;
52
- status: string;
53
- statusCode: number | null;
54
- responseTimeMs: number | null;
55
- attempts: number;
56
- error: string | null;
57
- createdAt: string;
58
- }
59
- interface DeliveryDetail extends DeliverySummary {
60
- payload: unknown;
61
- }
62
- interface DeliveriesResponse {
63
- deliveries: DeliverySummary[];
64
- }
65
- declare class Streams extends BaseClient {
66
- private requestWithStreamId;
67
- resolveStreamId(partialId: string): Promise<string>;
68
- create(data: CreateStream): Promise<CreateStreamResponse>;
69
- update(id: string, data: UpdateStream): Promise<StreamResponse>;
70
- updateByName(name: string, data: CreateStream): Promise<StreamResponse>;
71
- list(params?: {
72
- status?: string
73
- }): Promise<ListStreamsResponse>;
74
- get(id: string): Promise<StreamResponse>;
75
- delete(id: string): Promise<void>;
76
- enable(id: string): Promise<StreamResponse>;
77
- disable(id: string): Promise<StreamResponse>;
78
- rotateSecret(id: string): Promise<{
79
- secret: string
80
- }>;
81
- /** List recent deliveries for a stream. */
82
- listDeliveries(id: string, params?: {
83
- limit?: number
84
- status?: string
85
- }): Promise<DeliveriesResponse>;
86
- /** Get a single delivery with full payload. */
87
- getDelivery(streamId: string, deliveryId: string): Promise<DeliveryDetail>;
88
- pauseAll(): Promise<BulkPauseResponse>;
89
- resumeAll(): Promise<BulkResumeResponse>;
90
- }
91
51
  import { ReindexResponse, SubgraphDetail, SubgraphGapsResponse, SubgraphQueryParams as SubgraphQueryParams2, SubgraphSummary } from "@secondlayer/shared/schemas";
92
52
  import { DeploySubgraphRequest, DeploySubgraphResponse } from "@secondlayer/shared/schemas/subgraphs";
93
53
  import { InferSubgraphClient } from "@secondlayer/subgraphs";
54
+ interface SubgraphSource {
55
+ name: string;
56
+ version: string;
57
+ sourceCode: string | null;
58
+ readOnly: boolean;
59
+ reason?: string;
60
+ updatedAt: string;
61
+ }
62
+ interface BundleSubgraphResponse {
63
+ ok: true;
64
+ name: string;
65
+ version: string | null;
66
+ description: string | null;
67
+ sources: Record<string, Record<string, unknown>>;
68
+ schema: Record<string, unknown>;
69
+ handlerCode: string;
70
+ sourceCode: string;
71
+ bundleSize: number;
72
+ }
94
73
  declare class Subgraphs extends BaseClient {
95
74
  list(): Promise<{
96
75
  data: SubgraphSummary[]
@@ -116,6 +95,14 @@ declare class Subgraphs extends BaseClient {
116
95
  message: string
117
96
  }>;
118
97
  deploy(data: DeploySubgraphRequest): Promise<DeploySubgraphResponse>;
98
+ getSource(name: string): Promise<SubgraphSource>;
99
+ /**
100
+ * Bundle a TypeScript subgraph source on the server. Used by the web chat
101
+ * authoring loop so Vercel's serverless runtime doesn't have to run esbuild.
102
+ */
103
+ bundle(data: {
104
+ code: string
105
+ }): Promise<BundleSubgraphResponse>;
119
106
  queryTable(name: string, table: string, params?: SubgraphQueryParams2): Promise<unknown[]>;
120
107
  queryTableCount(name: string, table: string, params?: SubgraphQueryParams2): Promise<{
121
108
  count: number
@@ -139,12 +126,78 @@ declare class Subgraphs extends BaseClient {
139
126
  private createTableClient;
140
127
  }
141
128
  import { InferSubgraphClient as InferSubgraphClient2 } from "@secondlayer/subgraphs";
142
- import { QueueStats } from "@secondlayer/shared/types";
143
129
  import { WorkflowRun, WorkflowRunStatus } from "@secondlayer/workflows";
130
+ interface WorkflowSource {
131
+ name: string;
132
+ version: string;
133
+ sourceCode: string | null;
134
+ readOnly: boolean;
135
+ reason?: string;
136
+ updatedAt: string;
137
+ }
138
+ interface WorkflowStepEvent {
139
+ id: string;
140
+ stepIndex: number;
141
+ stepId: string;
142
+ stepType: string;
143
+ status: string;
144
+ output?: unknown;
145
+ error: string | null;
146
+ retryCount: number;
147
+ aiTokensUsed: number;
148
+ startedAt: string | null;
149
+ completedAt: string | null;
150
+ durationMs: number | null;
151
+ ts: string;
152
+ }
153
+ interface WorkflowRunDoneEvent {
154
+ runId: string;
155
+ status: string;
156
+ error?: string | null;
157
+ completedAt?: string | null;
158
+ }
159
+ type WorkflowTailEvent = {
160
+ type: "step"
161
+ step: WorkflowStepEvent
162
+ } | {
163
+ type: "done"
164
+ done: WorkflowRunDoneEvent
165
+ } | {
166
+ type: "heartbeat"
167
+ ts: string
168
+ } | {
169
+ type: "timeout"
170
+ message: string
171
+ };
172
+ interface DeployDryRunResponse {
173
+ valid: boolean;
174
+ validation?: {
175
+ name: string
176
+ triggerType: string
177
+ };
178
+ bundleSize: number;
179
+ error?: string;
180
+ }
181
+ interface DeployResponse {
182
+ action: "created" | "updated";
183
+ workflowId: string;
184
+ version: string;
185
+ message: string;
186
+ }
187
+ interface BundleWorkflowResponse {
188
+ ok: true;
189
+ name: string;
190
+ trigger: Record<string, unknown>;
191
+ handlerCode: string;
192
+ sourceCode: string;
193
+ retries: Record<string, unknown> | null;
194
+ timeout: number | null;
195
+ bundleSize: number;
196
+ }
144
197
  interface WorkflowSummary {
145
198
  name: string;
146
199
  status: "active" | "paused";
147
- triggerType: "event" | "stream" | "schedule" | "manual";
200
+ triggerType: "event" | "schedule" | "manual";
148
201
  createdAt: string;
149
202
  updatedAt: string;
150
203
  }
@@ -172,13 +225,63 @@ declare class Workflows extends BaseClient {
172
225
  name: string
173
226
  trigger: Record<string, unknown>
174
227
  handlerCode: string
228
+ sourceCode?: string
229
+ expectedVersion?: string
175
230
  retries?: Record<string, unknown>
176
231
  timeout?: number
177
- }): Promise<{
178
- action: string
179
- workflowId: string
180
- message: string
232
+ clientRequestId?: string
233
+ } & {
234
+ dryRun?: false
235
+ }): Promise<DeployResponse>;
236
+ deploy(data: {
237
+ name: string
238
+ trigger: Record<string, unknown>
239
+ handlerCode: string
240
+ sourceCode?: string
241
+ expectedVersion?: string
242
+ retries?: Record<string, unknown>
243
+ timeout?: number
244
+ dryRun: true
245
+ }): Promise<DeployDryRunResponse>;
246
+ getSource(name: string): Promise<WorkflowSource>;
247
+ /**
248
+ * Bundle a TypeScript workflow source on the server. Used by the web chat
249
+ * authoring loop so Vercel's serverless runtime doesn't have to run esbuild.
250
+ * CLI and MCP still bundle locally — this method is for clients that can't
251
+ * install `@secondlayer/bundler` directly (e.g. browser tooling, edge
252
+ * functions).
253
+ */
254
+ bundle(data: {
255
+ code: string
256
+ }): Promise<BundleWorkflowResponse>;
257
+ pauseAll(): Promise<{
258
+ paused: number
259
+ workflows: Array<{
260
+ name: string
261
+ version: string
262
+ status: string
263
+ }>
181
264
  }>;
265
+ cancelRun(runId: string): Promise<{
266
+ runId: string
267
+ status: string
268
+ cancelled: boolean
269
+ completedAt?: string
270
+ message?: string
271
+ }>;
272
+ rollback(name: string, toVersion?: string): Promise<{
273
+ action: "rolled-back"
274
+ name: string
275
+ fromVersion: string
276
+ restoredFromVersion: string
277
+ version: string
278
+ }>;
279
+ /**
280
+ * Subscribe to a workflow run's server-sent event stream. Resolves when the
281
+ * run completes, times out, or the signal is aborted. Throws on HTTP errors
282
+ * opening the stream.
283
+ */
284
+ streamRun(name: string, runId: string, onEvent: (event: WorkflowTailEvent) => void, signal?: AbortSignal): Promise<void>;
182
285
  list(): Promise<{
183
286
  workflows: WorkflowSummary[]
184
287
  }>;
@@ -198,12 +301,10 @@ declare class Workflows extends BaseClient {
198
301
  getRun(runId: string): Promise<WorkflowRun>;
199
302
  }
200
303
  declare class SecondLayer extends BaseClient {
201
- readonly streams: Streams;
202
304
  readonly subgraphs: Subgraphs;
203
305
  readonly marketplace: Marketplace;
204
306
  readonly workflows: Workflows;
205
307
  constructor(options?: Partial<SecondLayerOptions>);
206
- getQueueStats(): Promise<QueueStats>;
207
308
  }
208
309
  /**
209
310
  * Returns a typed client for a subgraph defined with `defineSubgraph()`.
@@ -230,10 +331,10 @@ declare function getSubgraph<T extends {
230
331
  * @example
231
332
  * ```ts
232
333
  * try {
233
- * await client.streams.get("abc123");
334
+ * await client.subgraphs.get("my-subgraph");
234
335
  * } catch (err) {
235
336
  * if (err instanceof ApiError && err.status === 404) {
236
- * console.log("Stream not found");
337
+ * console.log("Subgraph not found");
237
338
  * }
238
339
  * }
239
340
  * ```
@@ -241,7 +342,18 @@ declare function getSubgraph<T extends {
241
342
  declare class ApiError extends Error {
242
343
  /** HTTP status code (0 for network errors). */
243
344
  status: number;
244
- constructor(status: number, message: string);
345
+ /** Raw response body (parsed JSON if possible) — preserved for callers that need error details. */
346
+ body?: unknown;
347
+ constructor(status: number, message: string, body?: unknown);
348
+ }
349
+ /**
350
+ * Thrown by {@link Workflows.deploy} when the server rejects a deploy because the
351
+ * provided `expectedVersion` does not match the current stored version.
352
+ */
353
+ declare class VersionConflictError extends ApiError {
354
+ currentVersion: string;
355
+ expectedVersion: string;
356
+ constructor(currentVersion: string, expectedVersion: string, message?: string);
245
357
  }
246
358
  /**
247
359
  * Verify a webhook delivery signature from Secondlayer.
@@ -252,7 +364,7 @@ declare class ApiError extends Error {
252
364
  *
253
365
  * @param rawBody - The raw request body as a string (not parsed JSON)
254
366
  * @param signatureHeader - The value of the `x-secondlayer-signature` header
255
- * @param secret - Your stream's signing secret
367
+ * @param secret - Your signing secret
256
368
  * @param toleranceSeconds - Max age of signature in seconds (default 300)
257
369
  * @returns true if the signature is valid
258
370
  *
@@ -271,4 +383,4 @@ declare class ApiError extends Error {
271
383
  * ```
272
384
  */
273
385
  declare function verifyWebhookSignature(rawBody: string, signatureHeader: string, secret: string, toleranceSeconds?: number): boolean;
274
- export { verifyWebhookSignature, getSubgraph, Workflows, Subgraphs, Streams, SecondLayerOptions, SecondLayer, Marketplace, ApiError };
386
+ export { verifyWebhookSignature, getSubgraph, VersionConflictError, Subgraphs, SecondLayerOptions, SecondLayer, Marketplace, ApiError };
package/dist/index.js CHANGED
@@ -1,35 +1,51 @@
1
1
  // src/errors.ts
2
2
  class ApiError extends Error {
3
3
  status;
4
- constructor(status, message) {
4
+ body;
5
+ constructor(status, message, body) {
5
6
  super(message);
6
7
  this.status = status;
8
+ this.body = body;
7
9
  this.name = "ApiError";
8
10
  }
9
11
  }
10
12
 
13
+ class VersionConflictError extends ApiError {
14
+ currentVersion;
15
+ expectedVersion;
16
+ constructor(currentVersion, expectedVersion, message = `Version conflict: expected ${expectedVersion}, current ${currentVersion}`) {
17
+ super(409, message, { currentVersion, expectedVersion });
18
+ this.currentVersion = currentVersion;
19
+ this.expectedVersion = expectedVersion;
20
+ this.name = "VersionConflictError";
21
+ }
22
+ }
23
+
11
24
  // src/base.ts
12
25
  var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
13
26
 
14
27
  class BaseClient {
15
28
  baseUrl;
16
29
  apiKey;
30
+ origin;
17
31
  constructor(options = {}) {
18
32
  this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
19
33
  this.apiKey = options.apiKey;
34
+ this.origin = options.origin ?? "cli";
20
35
  }
21
36
  static authHeaders(apiKey) {
22
37
  const headers = {
23
38
  "Content-Type": "application/json"
24
39
  };
25
40
  if (apiKey) {
26
- headers["Authorization"] = `Bearer ${apiKey}`;
41
+ headers.Authorization = `Bearer ${apiKey}`;
27
42
  }
28
43
  return headers;
29
44
  }
30
45
  async request(method, path, body) {
31
46
  const url = `${this.baseUrl}${path}`;
32
47
  const headers = BaseClient.authHeaders(this.apiKey);
48
+ headers["x-sl-origin"] = this.origin;
33
49
  let response;
34
50
  try {
35
51
  response = await fetch(url, {
@@ -54,8 +70,10 @@ class BaseClient {
54
70
  }
55
71
  const errorBody = await response.text();
56
72
  let message = `HTTP ${response.status}`;
73
+ let parsedBody = errorBody;
57
74
  try {
58
75
  const json = JSON.parse(errorBody);
76
+ parsedBody = json;
59
77
  const err = json.error ?? json.message;
60
78
  if (typeof err === "string") {
61
79
  message = err;
@@ -66,7 +84,7 @@ class BaseClient {
66
84
  if (errorBody)
67
85
  message = errorBody;
68
86
  }
69
- throw new ApiError(response.status, message);
87
+ throw new ApiError(response.status, message, parsedBody);
70
88
  }
71
89
  if (response.status === 204) {
72
90
  return;
@@ -131,83 +149,6 @@ class Marketplace extends BaseClient {
131
149
  return this.request("GET", `/api/marketplace/subgraphs/${name}/${table}${buildSubgraphQueryString(params)}`);
132
150
  }
133
151
  }
134
- // src/streams/client.ts
135
- class Streams extends BaseClient {
136
- async requestWithStreamId(method, pathTemplate, id, body) {
137
- const fullId = await this.resolveStreamId(id);
138
- return this.request(method, pathTemplate(fullId), body);
139
- }
140
- async resolveStreamId(partialId) {
141
- if (partialId.length === 36 && partialId.includes("-")) {
142
- return partialId;
143
- }
144
- const { streams } = await this.list();
145
- const matches = streams.filter((s) => s.id.startsWith(partialId));
146
- if (matches.length === 0) {
147
- throw new ApiError(404, `No stream found matching "${partialId}"`);
148
- }
149
- if (matches.length > 1) {
150
- throw new ApiError(400, `Multiple streams match "${partialId}": ${matches.map((s) => s.id.slice(0, 8)).join(", ")}`);
151
- }
152
- return matches[0].id;
153
- }
154
- async create(data) {
155
- return this.request("POST", "/api/streams", data);
156
- }
157
- async update(id, data) {
158
- return this.requestWithStreamId("PATCH", (id2) => `/api/streams/${id2}`, id, data);
159
- }
160
- async updateByName(name, data) {
161
- const { streams } = await this.list();
162
- const existing = streams.find((s) => s.name === name);
163
- if (!existing) {
164
- throw new ApiError(404, `Stream with name "${name}" not found`);
165
- }
166
- return this.update(existing.id, data);
167
- }
168
- async list(params) {
169
- const searchParams = new URLSearchParams;
170
- if (params?.status)
171
- searchParams.set("status", params.status);
172
- const query = searchParams.toString();
173
- const path = query ? `/api/streams?${query}` : "/api/streams";
174
- return this.request("GET", path);
175
- }
176
- async get(id) {
177
- return this.requestWithStreamId("GET", (id2) => `/api/streams/${id2}`, id);
178
- }
179
- async delete(id) {
180
- return this.requestWithStreamId("DELETE", (id2) => `/api/streams/${id2}`, id);
181
- }
182
- async enable(id) {
183
- return this.requestWithStreamId("POST", (id2) => `/api/streams/${id2}/enable`, id);
184
- }
185
- async disable(id) {
186
- return this.requestWithStreamId("POST", (id2) => `/api/streams/${id2}/disable`, id);
187
- }
188
- async rotateSecret(id) {
189
- return this.requestWithStreamId("POST", (id2) => `/api/streams/${id2}/rotate-secret`, id);
190
- }
191
- async listDeliveries(id, params) {
192
- const qs = new URLSearchParams;
193
- if (params?.limit !== undefined)
194
- qs.set("limit", String(params.limit));
195
- if (params?.status)
196
- qs.set("status", params.status);
197
- const query = qs.toString();
198
- return this.requestWithStreamId("GET", (id2) => `/api/streams/${id2}/deliveries${query ? `?${query}` : ""}`, id);
199
- }
200
- async getDelivery(streamId, deliveryId) {
201
- const fullId = await this.resolveStreamId(streamId);
202
- return this.request("GET", `/api/streams/${fullId}/deliveries/${deliveryId}`);
203
- }
204
- async pauseAll() {
205
- return this.request("POST", "/api/streams/pause");
206
- }
207
- async resumeAll() {
208
- return this.request("POST", "/api/streams/resume");
209
- }
210
- }
211
152
  // src/subgraphs/serialize.ts
212
153
  var SYSTEM_COLUMN_MAP = {
213
154
  _blockHeight: "_block_height",
@@ -304,6 +245,12 @@ class Subgraphs extends BaseClient {
304
245
  async deploy(data) {
305
246
  return this.request("POST", "/api/subgraphs", data);
306
247
  }
248
+ async getSource(name) {
249
+ return this.request("GET", `/api/subgraphs/${name}/source`);
250
+ }
251
+ async bundle(data) {
252
+ return this.request("POST", "/api/subgraphs/bundle", data);
253
+ }
307
254
  async queryTable(name, table, params = {}) {
308
255
  const result = await this.request("GET", `/api/subgraphs/${name}/${table}${buildSubgraphQueryString2(params)}`);
309
256
  return Array.isArray(result) ? result : result.data;
@@ -358,9 +305,116 @@ class Subgraphs extends BaseClient {
358
305
  }
359
306
  }
360
307
  // src/workflows/client.ts
308
+ function parseSseChunk(raw) {
309
+ let event = "message";
310
+ const dataLines = [];
311
+ for (const line of raw.split(`
312
+ `)) {
313
+ if (line.startsWith("event:")) {
314
+ event = line.slice(6).trim();
315
+ } else if (line.startsWith("data:")) {
316
+ dataLines.push(line.slice(5).trimStart());
317
+ }
318
+ }
319
+ if (dataLines.length === 0)
320
+ return null;
321
+ const data = dataLines.join(`
322
+ `);
323
+ try {
324
+ const parsed = JSON.parse(data);
325
+ switch (event) {
326
+ case "step":
327
+ return { type: "step", step: parsed };
328
+ case "done":
329
+ return { type: "done", done: parsed };
330
+ case "heartbeat":
331
+ return {
332
+ type: "heartbeat",
333
+ ts: typeof parsed === "string" ? parsed : String(parsed)
334
+ };
335
+ case "timeout":
336
+ return {
337
+ type: "timeout",
338
+ message: parsed.message ?? "timeout"
339
+ };
340
+ default:
341
+ return null;
342
+ }
343
+ } catch {
344
+ return null;
345
+ }
346
+ }
347
+
361
348
  class Workflows extends BaseClient {
362
349
  async deploy(data) {
363
- return this.request("POST", "/api/workflows", data);
350
+ try {
351
+ return await this.request("POST", "/api/workflows", data);
352
+ } catch (err) {
353
+ if (err instanceof ApiError && err.status === 409) {
354
+ const body = err.body;
355
+ if (body?.currentVersion && body.expectedVersion) {
356
+ throw new VersionConflictError(body.currentVersion, body.expectedVersion, err.message);
357
+ }
358
+ }
359
+ throw err;
360
+ }
361
+ }
362
+ async getSource(name) {
363
+ return this.request("GET", `/api/workflows/${name}/source`);
364
+ }
365
+ async bundle(data) {
366
+ return this.request("POST", "/api/workflows/bundle", data);
367
+ }
368
+ async pauseAll() {
369
+ return this.request("POST", "/api/workflows/pause-all");
370
+ }
371
+ async cancelRun(runId) {
372
+ return this.request("POST", `/api/workflows/runs/${runId}/cancel`);
373
+ }
374
+ async rollback(name, toVersion) {
375
+ return this.request("POST", `/api/workflows/${name}/rollback`, toVersion ? { toVersion } : {});
376
+ }
377
+ async streamRun(name, runId, onEvent, signal) {
378
+ const url = `${this.baseUrl}/api/workflows/${name}/runs/${runId}/stream`;
379
+ const headers = {
380
+ Accept: "text/event-stream",
381
+ "x-sl-origin": this.origin
382
+ };
383
+ if (this.apiKey) {
384
+ headers.Authorization = `Bearer ${this.apiKey}`;
385
+ }
386
+ const res = await fetch(url, { headers, signal });
387
+ if (!res.ok || !res.body) {
388
+ throw new ApiError(res.status, `Failed to open workflow run stream (HTTP ${res.status})`);
389
+ }
390
+ const reader = res.body.pipeThrough(new TextDecoderStream).getReader();
391
+ let buffer = "";
392
+ while (true) {
393
+ const { value, done } = await reader.read();
394
+ if (done)
395
+ break;
396
+ buffer += value;
397
+ let sep = buffer.indexOf(`
398
+
399
+ `);
400
+ while (sep !== -1) {
401
+ const chunk = buffer.slice(0, sep);
402
+ buffer = buffer.slice(sep + 2);
403
+ const parsed = parseSseChunk(chunk);
404
+ if (parsed) {
405
+ onEvent(parsed);
406
+ if (parsed.type === "done" || parsed.type === "timeout") {
407
+ await reader.cancel().catch(() => {
408
+ return;
409
+ });
410
+ return;
411
+ }
412
+ }
413
+ sep = buffer.indexOf(`
414
+
415
+ `);
416
+ }
417
+ }
364
418
  }
365
419
  async list() {
366
420
  return this.request("GET", "/api/workflows");
@@ -396,21 +450,15 @@ class Workflows extends BaseClient {
396
450
 
397
451
  // src/client.ts
398
452
  class SecondLayer extends BaseClient {
399
- streams;
400
453
  subgraphs;
401
454
  marketplace;
402
455
  workflows;
403
456
  constructor(options = {}) {
404
457
  super(options);
405
- this.streams = new Streams(options);
406
458
  this.subgraphs = new Subgraphs(options);
407
459
  this.marketplace = new Marketplace(options);
408
460
  this.workflows = new Workflows(options);
409
461
  }
410
- async getQueueStats() {
411
- const status = await this.request("GET", "/status");
412
- return status.queue;
413
- }
414
462
  }
415
463
 
416
464
  // src/subgraphs/get-subgraph.ts
@@ -431,13 +479,12 @@ function verifyWebhookSignature(rawBody, signatureHeader, secret, toleranceSecon
431
479
  export {
432
480
  verifyWebhookSignature,
433
481
  getSubgraph,
434
- Workflows,
482
+ VersionConflictError,
435
483
  Subgraphs,
436
- Streams,
437
484
  SecondLayer,
438
485
  Marketplace,
439
486
  ApiError
440
487
  };
441
488
 
442
- //# debugId=078A8B332D40B93464756E2164756E21
489
+ //# debugId=E50F894A60802FF364756E2164756E21
443
490
  //# sourceMappingURL=index.js.map