@zergai/zergbox-client 0.1.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 +86 -0
- package/dist/chunk-KLBU4HNA.js +1311 -0
- package/dist/index.js +26 -0
- package/dist/sync.js +1946 -0
- package/index.d.ts +211 -0
- package/package.json +56 -0
- package/sync.d.ts +58 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
export type SyncNodeType = 'directory' | 'file'
|
|
2
|
+
|
|
3
|
+
export interface SyncNode {
|
|
4
|
+
id: string
|
|
5
|
+
path: string
|
|
6
|
+
type: SyncNodeType
|
|
7
|
+
revision?: number
|
|
8
|
+
contentHash?: string
|
|
9
|
+
sizeBytes?: number
|
|
10
|
+
updatedAt?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type SyncChangeType =
|
|
14
|
+
| 'create_remote_folder'
|
|
15
|
+
| 'move_remote_folder'
|
|
16
|
+
| 'upload_file'
|
|
17
|
+
| 'move_remote_file'
|
|
18
|
+
| 'create_local_folder'
|
|
19
|
+
| 'move_local_folder'
|
|
20
|
+
| 'download_file'
|
|
21
|
+
| 'move_local_file'
|
|
22
|
+
| 'conflict'
|
|
23
|
+
| 'delete_remote'
|
|
24
|
+
| 'delete_remote_folder'
|
|
25
|
+
| 'delete_local'
|
|
26
|
+
| 'delete_local_folder'
|
|
27
|
+
|
|
28
|
+
export interface SyncChange {
|
|
29
|
+
type: SyncChangeType
|
|
30
|
+
path: string
|
|
31
|
+
fromPath?: string
|
|
32
|
+
reason?: string
|
|
33
|
+
remoteId?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type MergeCandidateState = 'pending' | 'resolved' | 'dismissed'
|
|
37
|
+
|
|
38
|
+
export interface MergeCandidate {
|
|
39
|
+
id: string
|
|
40
|
+
path: string
|
|
41
|
+
state: MergeCandidateState
|
|
42
|
+
base?: SyncNode
|
|
43
|
+
local: SyncNode
|
|
44
|
+
remote: SyncNode
|
|
45
|
+
createdAt?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const SYNC_NODE_TYPES: readonly SyncNodeType[]
|
|
49
|
+
export const SYNC_CHANGE_TYPES: readonly SyncChangeType[]
|
|
50
|
+
export const MERGE_CANDIDATE_STATES: readonly MergeCandidateState[]
|
|
51
|
+
|
|
52
|
+
export function isSyncNode(value: unknown): value is SyncNode
|
|
53
|
+
export function isSyncChange(value: unknown): value is SyncChange
|
|
54
|
+
export function isMergeCandidate(value: unknown): value is MergeCandidate
|
|
55
|
+
|
|
56
|
+
export interface ZergBoxClientOptions {
|
|
57
|
+
baseUrl: string
|
|
58
|
+
token: string
|
|
59
|
+
requestTimeoutMs?: number
|
|
60
|
+
maxResponseBytes?: number
|
|
61
|
+
maxDownloadBytes?: number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ZergBoxOrganization {
|
|
65
|
+
id: string
|
|
66
|
+
name: string
|
|
67
|
+
slug?: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ZergBoxFolder {
|
|
71
|
+
id: string
|
|
72
|
+
name: string
|
|
73
|
+
parent_folder_id?: string | null
|
|
74
|
+
revision: number
|
|
75
|
+
updated_at?: string
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ZergBoxFile {
|
|
79
|
+
id: string
|
|
80
|
+
name: string
|
|
81
|
+
folder_id?: string
|
|
82
|
+
mime_type?: string
|
|
83
|
+
size_bytes?: number
|
|
84
|
+
current_version?: number
|
|
85
|
+
content_sha256: string
|
|
86
|
+
revision: number
|
|
87
|
+
updated_at?: string
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface ZergBoxFolderListing {
|
|
91
|
+
folder: ZergBoxFolder
|
|
92
|
+
folders: ZergBoxFolder[]
|
|
93
|
+
files: ZergBoxFile[]
|
|
94
|
+
breadcrumbs?: ZergBoxFolder[]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ZergBoxMutationResult {
|
|
98
|
+
id?: string
|
|
99
|
+
folder?: ZergBoxFolder
|
|
100
|
+
file?: ZergBoxFile
|
|
101
|
+
version?: number
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type ZergBoxChangeKind = 'created' | 'content' | 'moved' | 'deleted' | 'restored'
|
|
105
|
+
|
|
106
|
+
export interface ZergBoxContentChange {
|
|
107
|
+
cursor: number
|
|
108
|
+
entry_id: string
|
|
109
|
+
entry_kind: 'file' | 'folder'
|
|
110
|
+
change_kind: ZergBoxChangeKind
|
|
111
|
+
entry_name: string
|
|
112
|
+
parent_folder_id: string | null
|
|
113
|
+
previous_parent_folder_id: string | null
|
|
114
|
+
revision: number
|
|
115
|
+
content_sha256: string | null
|
|
116
|
+
created_at: string
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface ZergBoxChangePage {
|
|
120
|
+
rootFolderId: string
|
|
121
|
+
changes: ZergBoxContentChange[]
|
|
122
|
+
nextCursor: number
|
|
123
|
+
hasMore: boolean
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ZergBoxByteUpload {
|
|
127
|
+
orgId: string
|
|
128
|
+
folderId: string
|
|
129
|
+
filename: string
|
|
130
|
+
bytes: Uint8Array
|
|
131
|
+
mediaType?: string
|
|
132
|
+
expectedAbsent?: true
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface ZergBoxSyncClient {
|
|
136
|
+
getRootFolder(organizationId: string, options?: { limit?: number; offset?: number }): Promise<ZergBoxFolderListing>
|
|
137
|
+
getFolder(folderId: string, options?: { limit?: number; offset?: number }): Promise<ZergBoxFolderListing>
|
|
138
|
+
listChanges(rootFolderId: string, options?: { cursor?: number; limit?: number }): Promise<ZergBoxChangePage>
|
|
139
|
+
getChanges(input: { rootFolderId: string; cursor?: number; limit?: number }): Promise<ZergBoxChangePage>
|
|
140
|
+
createFolder(input: { orgId: string; parentFolderId: string; name: string; expectedAbsent?: true }): Promise<ZergBoxMutationResult>
|
|
141
|
+
updateFolder(input: { folderId: string; name?: string; parentFolderId?: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
142
|
+
uploadBytes(input: ZergBoxByteUpload): Promise<ZergBoxMutationResult>
|
|
143
|
+
uploadFile(input: { orgId: string; folderId: string; filePath: string; filename?: string; replaceExisting?: boolean }): Promise<ZergBoxMutationResult>
|
|
144
|
+
updateFileBytes(input: { fileId: string; filename?: string; bytes: Uint8Array; mediaType?: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
145
|
+
updateFileContent(input: { fileId: string; filePath: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
146
|
+
updateFile(input: { fileId: string; name?: string; folderId?: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
147
|
+
downloadFile(fileId: string, options?: { maxBytes?: number }): Promise<Uint8Array>
|
|
148
|
+
deleteRemoteFile(fileId: string, options: { expectedRevision: number }): Promise<unknown>
|
|
149
|
+
deleteRemoteFolder(folderId: string, options: { expectedRevision: number }): Promise<unknown>
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface RemoteTree {
|
|
153
|
+
rootFolder: ZergBoxFolder
|
|
154
|
+
entries: SyncNode[]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface ZergBoxApiErrorDetails {
|
|
158
|
+
status?: number
|
|
159
|
+
body?: string
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface ZergBoxSyncConflictDetails extends ZergBoxApiErrorDetails {
|
|
163
|
+
resourceType: 'file' | 'folder'
|
|
164
|
+
resourceId: string | null
|
|
165
|
+
resourcePath?: string
|
|
166
|
+
expectedRevision?: number
|
|
167
|
+
expectedAbsent?: true
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export class ZergBoxApiError extends Error {
|
|
171
|
+
constructor(message: string, details?: ZergBoxApiErrorDetails)
|
|
172
|
+
status?: number
|
|
173
|
+
body?: string
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export class ZergBoxSyncConflictError extends ZergBoxApiError {
|
|
177
|
+
constructor(message: string, details: ZergBoxSyncConflictDetails)
|
|
178
|
+
code: 'SYNC_CONFLICT'
|
|
179
|
+
recoverable: true
|
|
180
|
+
resourceType: 'file' | 'folder'
|
|
181
|
+
resourceId: string | null
|
|
182
|
+
resourcePath?: string
|
|
183
|
+
expectedRevision?: number
|
|
184
|
+
expectedAbsent?: true
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export class ZergBoxClient implements ZergBoxSyncClient {
|
|
188
|
+
constructor(options: ZergBoxClientOptions)
|
|
189
|
+
listOrganizations(): Promise<ZergBoxOrganization[]>
|
|
190
|
+
getRootFolder(organizationId: string, options?: { limit?: number; offset?: number }): Promise<ZergBoxFolderListing>
|
|
191
|
+
getFolder(folderId: string, options?: { limit?: number; offset?: number }): Promise<ZergBoxFolderListing>
|
|
192
|
+
listChanges(rootFolderId: string, options?: { cursor?: number; limit?: number }): Promise<ZergBoxChangePage>
|
|
193
|
+
getChanges(input: { rootFolderId: string; cursor?: number; limit?: number }): Promise<ZergBoxChangePage>
|
|
194
|
+
createFolder(input: { orgId: string; parentFolderId: string; name: string; expectedAbsent?: true }): Promise<ZergBoxMutationResult>
|
|
195
|
+
updateFolder(input: { folderId: string; name?: string; parentFolderId?: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
196
|
+
uploadBytes(input: ZergBoxByteUpload): Promise<ZergBoxMutationResult>
|
|
197
|
+
uploadFile(input: { orgId: string; folderId: string; filePath: string; filename?: string; replaceExisting?: boolean }): Promise<ZergBoxMutationResult>
|
|
198
|
+
updateFileBytes(input: { fileId: string; filename?: string; bytes: Uint8Array; mediaType?: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
199
|
+
updateFileContent(input: { fileId: string; filePath: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
200
|
+
updateFile(input: { fileId: string; name?: string; folderId?: string; expectedRevision: number }): Promise<ZergBoxMutationResult>
|
|
201
|
+
downloadFile(fileId: string, options?: { maxBytes?: number }): Promise<Uint8Array>
|
|
202
|
+
deleteRemoteFile(fileId: string, options: { expectedRevision: number }): Promise<unknown>
|
|
203
|
+
deleteRemoteFolder(folderId: string, options: { expectedRevision: number }): Promise<unknown>
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function fetchRemoteTree(
|
|
207
|
+
client: Pick<ZergBoxSyncClient, 'getRootFolder' | 'getFolder'>,
|
|
208
|
+
options: { orgId: string; rootFolderId?: string; pageSize?: number }
|
|
209
|
+
): Promise<RemoteTree>
|
|
210
|
+
|
|
211
|
+
export function remoteFileFingerprint(file: Partial<ZergBoxFile>): string
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zergai/zergbox-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Typed ZergBox API and bounded local sync client",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"packageManager": "npm@11.5.1",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=22.19.0 <25",
|
|
12
|
+
"npm": ">=10.9.2 <12"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./sync": {
|
|
20
|
+
"types": "./sync.d.ts",
|
|
21
|
+
"import": "./dist/sync.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"index.d.ts",
|
|
27
|
+
"sync.d.ts",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "node ./scripts/build.mjs",
|
|
32
|
+
"prepack": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"esbuild": "0.27.3"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public",
|
|
39
|
+
"provenance": false
|
|
40
|
+
},
|
|
41
|
+
"license": "UNLICENSED",
|
|
42
|
+
"homepage": "https://zergbox.com",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/Epoch-ML/zerg/issues"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/Epoch-ML/zerg.git",
|
|
49
|
+
"directory": "zapps/zergbox/client"
|
|
50
|
+
},
|
|
51
|
+
"keywords": [
|
|
52
|
+
"zergbox",
|
|
53
|
+
"file-sync",
|
|
54
|
+
"knowledge-base"
|
|
55
|
+
]
|
|
56
|
+
}
|
package/sync.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { SyncChange, ZergBoxSyncClient } from './index.js'
|
|
2
|
+
|
|
3
|
+
export * from './index.js'
|
|
4
|
+
|
|
5
|
+
export type TokenProvider = () => Promise<string | { token: string }> | string | { token: string }
|
|
6
|
+
|
|
7
|
+
export interface CreateSyncSessionOptions {
|
|
8
|
+
client?: ZergBoxSyncClient
|
|
9
|
+
baseUrl?: string
|
|
10
|
+
tokenProvider?: TokenProvider
|
|
11
|
+
organizationId: string
|
|
12
|
+
rootFolderId: string
|
|
13
|
+
localRoot: string
|
|
14
|
+
statePath?: string
|
|
15
|
+
deviceId: string
|
|
16
|
+
intervalMs?: number
|
|
17
|
+
debounceMs?: number
|
|
18
|
+
requestTimeoutMs?: number
|
|
19
|
+
afterSync?: (result: SyncResult) => Promise<void> | void
|
|
20
|
+
onError?: (error: Error) => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SyncResult {
|
|
24
|
+
actions: SyncChange[]
|
|
25
|
+
localRoot: string
|
|
26
|
+
statePath: string
|
|
27
|
+
syncedAt: string | null
|
|
28
|
+
paused: boolean
|
|
29
|
+
locked: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SyncStatus {
|
|
33
|
+
state: string
|
|
34
|
+
paused: boolean
|
|
35
|
+
watching: boolean
|
|
36
|
+
closed: boolean
|
|
37
|
+
deviceId: string
|
|
38
|
+
organizationId: string
|
|
39
|
+
rootFolderId: string
|
|
40
|
+
localRoot: string
|
|
41
|
+
statePath: string
|
|
42
|
+
lastSyncedAt: string | null
|
|
43
|
+
actionCount: number | null
|
|
44
|
+
conflictCount: number | null
|
|
45
|
+
errorMessage: string | null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface SyncSession {
|
|
49
|
+
syncOnce(options?: { force?: boolean }): Promise<SyncResult>
|
|
50
|
+
watch(options?: { immediate?: boolean }): Promise<SyncStatus>
|
|
51
|
+
status(): Promise<SyncStatus>
|
|
52
|
+
pause(reason?: string): Promise<SyncStatus>
|
|
53
|
+
resume(): Promise<SyncStatus>
|
|
54
|
+
stopWatching(): Promise<SyncStatus>
|
|
55
|
+
close(): Promise<SyncStatus>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function createSyncSession(options: CreateSyncSessionOptions): SyncSession
|