@relayfile/sdk 0.3.1 → 0.4.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/dist/client.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type QueryFilesOptions, type SyncIngressStatusResponse, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type AckWritebackInput, type AckWritebackResponse } from "./types.js";
1
+ import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type CommitForkInput, type CommitForkResponse, type CreateForkInput, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type DiscardForkInput, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type ReadFileInput, type QueryFilesOptions, type SyncIngressStatusResponse, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type AckWritebackInput, type AckWritebackResponse } from "./types.js";
2
+ import type { ForkHandle } from "@relayfile/core";
2
3
  /**
3
4
  * Bearer token or token factory used for Relayfile API requests.
4
5
  *
@@ -52,10 +53,14 @@ export declare class RelayFileClient {
52
53
  constructor(options: RelayFileClientOptions);
53
54
  listTree(workspaceId: string, options?: ListTreeOptions): Promise<TreeResponse>;
54
55
  readFile(workspaceId: string, path: string, correlationId?: string, signal?: AbortSignal): Promise<FileReadResponse>;
56
+ readFile(input: ReadFileInput): Promise<FileReadResponse>;
55
57
  queryFiles(workspaceId: string, options?: QueryFilesOptions): Promise<FileQueryResponse>;
56
58
  writeFile(input: WriteFileInput): Promise<WriteQueuedResponse>;
57
59
  bulkWrite(input: BulkWriteInput): Promise<BulkWriteResponse>;
58
60
  deleteFile(input: DeleteFileInput): Promise<WriteQueuedResponse>;
61
+ createFork(input: CreateForkInput): Promise<ForkHandle>;
62
+ discardFork(input: DiscardForkInput): Promise<void>;
63
+ commitFork(input: CommitForkInput): Promise<CommitForkResponse>;
59
64
  getEvents(workspaceId: string, options?: GetEventsOptions): Promise<EventFeedResponse>;
60
65
  exportWorkspace(options: ExportOptions): Promise<ExportJsonResponse | Blob>;
61
66
  connectWebSocket(workspaceId: string, options?: ConnectWebSocketOptions): WebSocketConnection;
package/dist/client.js CHANGED
@@ -80,6 +80,18 @@ function normalizeExportJsonResponse(payload) {
80
80
  files: Array.isArray(data.files) ? data.files : []
81
81
  };
82
82
  }
83
+ function normalizeErrorDetails(data, explicitDetails) {
84
+ if (explicitDetails && typeof explicitDetails === "object" && !Array.isArray(explicitDetails)) {
85
+ return explicitDetails;
86
+ }
87
+ const details = {};
88
+ for (const [key, value] of Object.entries(data)) {
89
+ if (key !== "code" && key !== "message" && key !== "correlationId") {
90
+ details[key] = value;
91
+ }
92
+ }
93
+ return Object.keys(details).length > 0 ? details : undefined;
94
+ }
83
95
  class RelayFileWebSocketConnection {
84
96
  socket;
85
97
  handlers = {
@@ -163,7 +175,8 @@ export class RelayFileClient {
163
175
  const query = buildQuery({
164
176
  path: options.path ?? "/",
165
177
  depth: options.depth,
166
- cursor: options.cursor
178
+ cursor: options.cursor,
179
+ forkId: options.forkId
167
180
  });
168
181
  return this.request({
169
182
  method: "GET",
@@ -172,13 +185,21 @@ export class RelayFileClient {
172
185
  signal: options.signal
173
186
  });
174
187
  }
175
- async readFile(workspaceId, path, correlationId, signal) {
176
- const query = buildQuery({ path });
188
+ async readFile(workspaceOrInput, path, correlationId, signal) {
189
+ const input = typeof workspaceOrInput === "string"
190
+ ? {
191
+ workspaceId: workspaceOrInput,
192
+ path: path ?? "",
193
+ correlationId,
194
+ signal
195
+ }
196
+ : workspaceOrInput;
197
+ const query = buildQuery({ path: input.path, forkId: input.forkId });
177
198
  return this.request({
178
199
  method: "GET",
179
- path: `/v1/workspaces/${encodeURIComponent(workspaceId)}/fs/file${query}`,
180
- correlationId,
181
- signal
200
+ path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/file${query}`,
201
+ correlationId: input.correlationId,
202
+ signal: input.signal
182
203
  });
183
204
  }
184
205
  async queryFiles(workspaceId, options = {}) {
@@ -197,6 +218,8 @@ export class RelayFileClient {
197
218
  params.set("cursor", options.cursor);
198
219
  if (options.limit !== undefined)
199
220
  params.set("limit", String(options.limit));
221
+ if (options.forkId !== undefined)
222
+ params.set("forkId", options.forkId);
200
223
  if (options.properties !== undefined) {
201
224
  for (const [key, value] of Object.entries(options.properties)) {
202
225
  if (key !== "" && value !== undefined) {
@@ -215,7 +238,7 @@ export class RelayFileClient {
215
238
  }
216
239
  async writeFile(input) {
217
240
  const { workspaceId, path, correlationId, baseRevision, content, contentType, encoding, contentIdentity, signal } = input;
218
- const query = buildQuery({ path });
241
+ const query = buildQuery({ path, forkId: input.forkId });
219
242
  return this.request({
220
243
  method: "PUT",
221
244
  path: `/v1/workspaces/${encodeURIComponent(workspaceId)}/fs/file${query}`,
@@ -235,9 +258,10 @@ export class RelayFileClient {
235
258
  });
236
259
  }
237
260
  async bulkWrite(input) {
261
+ const query = buildQuery({ forkId: input.forkId });
238
262
  const response = await this.performRequest({
239
263
  method: "POST",
240
- path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/bulk`,
264
+ path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/bulk${query}`,
241
265
  correlationId: input.correlationId,
242
266
  body: {
243
267
  files: input.files
@@ -247,7 +271,7 @@ export class RelayFileClient {
247
271
  return this.readPayload(response);
248
272
  }
249
273
  async deleteFile(input) {
250
- const query = buildQuery({ path: input.path });
274
+ const query = buildQuery({ path: input.path, forkId: input.forkId });
251
275
  return this.request({
252
276
  method: "DELETE",
253
277
  path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/fs/file${query}`,
@@ -258,6 +282,37 @@ export class RelayFileClient {
258
282
  signal: input.signal
259
283
  });
260
284
  }
285
+ async createFork(input) {
286
+ const body = {
287
+ proposalId: input.proposalId
288
+ };
289
+ if (input.ttlSeconds !== undefined) {
290
+ body.ttlSeconds = input.ttlSeconds;
291
+ }
292
+ return this.request({
293
+ method: "POST",
294
+ path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/forks`,
295
+ correlationId: input.correlationId,
296
+ body,
297
+ signal: input.signal
298
+ });
299
+ }
300
+ async discardFork(input) {
301
+ await this.performRequest({
302
+ method: "DELETE",
303
+ path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/forks/${encodeURIComponent(input.forkId)}`,
304
+ correlationId: input.correlationId,
305
+ signal: input.signal
306
+ });
307
+ }
308
+ async commitFork(input) {
309
+ return this.request({
310
+ method: "POST",
311
+ path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/forks/${encodeURIComponent(input.forkId)}/commit`,
312
+ correlationId: input.correlationId,
313
+ signal: input.signal
314
+ });
315
+ }
261
316
  async getEvents(workspaceId, options = {}) {
262
317
  const query = buildQuery({
263
318
  provider: options.provider,
@@ -649,7 +704,9 @@ export class RelayFileClient {
649
704
  };
650
705
  }
651
706
  throwForError(status, payload, headers) {
652
- const data = (payload ?? {});
707
+ const rawData = (payload ?? {});
708
+ const data = rawData;
709
+ const details = normalizeErrorDetails(rawData, data.details);
653
710
  if (status === 409 &&
654
711
  typeof data.expectedRevision === "string" &&
655
712
  typeof data.currentRevision === "string") {
@@ -657,7 +714,7 @@ export class RelayFileClient {
657
714
  code: data.code ?? "revision_conflict",
658
715
  message: data.message ?? "Revision conflict",
659
716
  correlationId: data.correlationId ?? "",
660
- details: data.details,
717
+ details,
661
718
  expectedRevision: data.expectedRevision,
662
719
  currentRevision: data.currentRevision,
663
720
  currentContentPreview: data.currentContentPreview
@@ -668,7 +725,7 @@ export class RelayFileClient {
668
725
  code: data.code,
669
726
  message: data.message ?? "Invalid resource state",
670
727
  correlationId: data.correlationId,
671
- details: data.details
728
+ details
672
729
  });
673
730
  }
674
731
  if (status === 429 && data.code === "queue_full") {
@@ -684,7 +741,7 @@ export class RelayFileClient {
684
741
  code: data.code,
685
742
  message: data.message ?? "Ingress queue full",
686
743
  correlationId: data.correlationId,
687
- details: data.details
744
+ details
688
745
  }, retryAfterSeconds);
689
746
  }
690
747
  if (status === 413) {
@@ -692,14 +749,14 @@ export class RelayFileClient {
692
749
  code: data.code ?? "payload_too_large",
693
750
  message: data.message ?? "Request payload exceeds configured limit",
694
751
  correlationId: data.correlationId,
695
- details: data.details
752
+ details
696
753
  });
697
754
  }
698
755
  throw new RelayFileApiError(status, {
699
756
  code: data.code ?? "api_error",
700
757
  message: data.message ?? `HTTP ${status}`,
701
758
  correlationId: data.correlationId,
702
- details: data.details
759
+ details
703
760
  });
704
761
  }
705
762
  }
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ export { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiEr
4
4
  export { IntegrationProvider, computeCanonicalPath } from "./provider.js";
5
5
  export type { WebhookInput, ListProviderFilesOptions, WatchProviderEventsOptions } from "./provider.js";
6
6
  export type { ConnectionProvider, NormalizedWebhook, ProxyHeaders, ProxyMethod, ProxyQuery, ProxyRequest, ProxyResponse, } from "./connection.js";
7
- export type { AckResponse, AckWritebackInput, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, ConflictErrorResponse, ContentIdentity, DeleteFileInput, DeadLetterFeedResponse, DeadLetterItem, ErrorResponse, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, IngestWebhookInput, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, RelayFileJwtClaims, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, TreeEntry, TreeResponse, WritebackActionType, WritebackState, WritebackItem, WriteFileInput, WriteQueuedResponse } from "./types.js";
7
+ export type { AckResponse, AckWritebackInput, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, CommitForkInput, CommitForkResponse, ConflictErrorResponse, CreateForkInput, ContentIdentity, DeleteFileInput, DeadLetterFeedResponse, DeadLetterItem, DiscardForkInput, ErrorResponse, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, IngestWebhookInput, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, ReadFileInput, RelayFileJwtClaims, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, TreeEntry, TreeResponse, WritebackActionType, WritebackState, WritebackItem, WriteFileInput, WriteQueuedResponse } from "./types.js";
8
+ export type { ForkHandle, ForkOptions } from "@relayfile/core";
8
9
  export { WritebackConsumer } from "./writeback-consumer.js";
9
10
  export type { WritebackHandler, WritebackConsumerOptions } from "./writeback-consumer.js";
10
11
  export * from "./integration-adapter.js";
package/dist/types.d.ts CHANGED
@@ -83,6 +83,7 @@ export interface BulkWriteFile {
83
83
  export interface BulkWriteInput {
84
84
  workspaceId: string;
85
85
  files: BulkWriteFile[];
86
+ forkId?: string;
86
87
  correlationId?: string;
87
88
  signal?: AbortSignal;
88
89
  }
@@ -324,6 +325,7 @@ export interface ListTreeOptions {
324
325
  path?: string;
325
326
  depth?: number;
326
327
  cursor?: string;
328
+ forkId?: string;
327
329
  correlationId?: string;
328
330
  signal?: AbortSignal;
329
331
  }
@@ -336,6 +338,14 @@ export interface QueryFilesOptions {
336
338
  properties?: Record<string, string>;
337
339
  cursor?: string;
338
340
  limit?: number;
341
+ forkId?: string;
342
+ correlationId?: string;
343
+ signal?: AbortSignal;
344
+ }
345
+ export interface ReadFileInput {
346
+ workspaceId: string;
347
+ path: string;
348
+ forkId?: string;
339
349
  correlationId?: string;
340
350
  signal?: AbortSignal;
341
351
  }
@@ -448,6 +458,7 @@ export interface WriteFileInput {
448
458
  contentType?: string;
449
459
  encoding?: "utf-8" | "base64";
450
460
  semantics?: FileSemantics;
461
+ forkId?: string;
451
462
  contentIdentity?: ContentIdentity;
452
463
  correlationId?: string;
453
464
  signal?: AbortSignal;
@@ -456,9 +467,34 @@ export interface DeleteFileInput {
456
467
  workspaceId: string;
457
468
  path: string;
458
469
  baseRevision: string;
470
+ forkId?: string;
459
471
  correlationId?: string;
460
472
  signal?: AbortSignal;
461
473
  }
474
+ export interface CreateForkInput {
475
+ workspaceId: string;
476
+ proposalId: string;
477
+ ttlSeconds?: number;
478
+ correlationId?: string;
479
+ signal?: AbortSignal;
480
+ }
481
+ export interface DiscardForkInput {
482
+ workspaceId: string;
483
+ forkId: string;
484
+ correlationId?: string;
485
+ signal?: AbortSignal;
486
+ }
487
+ export interface CommitForkInput {
488
+ workspaceId: string;
489
+ forkId: string;
490
+ correlationId?: string;
491
+ signal?: AbortSignal;
492
+ }
493
+ export interface CommitForkResponse {
494
+ revision: string;
495
+ writtenCount: number;
496
+ deletedCount: number;
497
+ }
462
498
  export interface IngestWebhookInput {
463
499
  workspaceId: string;
464
500
  provider: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relayfile/sdk",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "TypeScript SDK for relayfile — real-time filesystem for humans and agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,6 +14,9 @@
14
14
  "test": "vitest run",
15
15
  "prepublishOnly": "npm run build"
16
16
  },
17
+ "dependencies": {
18
+ "@relayfile/core": "0.4.0"
19
+ },
17
20
  "devDependencies": {
18
21
  "typescript": "^5.7.3",
19
22
  "vitest": "^3.0.0"