@irpclib/irpc 1.2.0 → 1.2.2
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/enum.d.ts +1 -0
- package/dist/enum.js +1 -0
- package/dist/file.d.ts +28 -1
- package/dist/file.js +89 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/module.js +3 -1
- package/dist/packet.d.ts +29 -1
- package/dist/packet.js +54 -5
- package/dist/stream.js +5 -4
- package/dist/types.d.ts +3 -3
- package/package.json +2 -2
package/dist/enum.d.ts
CHANGED
package/dist/enum.js
CHANGED
package/dist/file.d.ts
CHANGED
|
@@ -26,6 +26,33 @@ declare class IRPCFile {
|
|
|
26
26
|
data: Blob;
|
|
27
27
|
constructor(meta: IRPCFileMeta, data?: Blob);
|
|
28
28
|
}
|
|
29
|
+
declare class IRPCBlob {
|
|
30
|
+
url: string;
|
|
31
|
+
meta?: {
|
|
32
|
+
type?: string;
|
|
33
|
+
size?: number;
|
|
34
|
+
name?: string;
|
|
35
|
+
} | undefined;
|
|
36
|
+
protected state: IRPCFileState;
|
|
37
|
+
data: Blob;
|
|
38
|
+
private pipes;
|
|
39
|
+
private promise;
|
|
40
|
+
private controller?;
|
|
41
|
+
get status(): IRPCFileStatus;
|
|
42
|
+
get error(): Error | undefined;
|
|
43
|
+
get downloaded(): number;
|
|
44
|
+
get success(): boolean;
|
|
45
|
+
get completed(): boolean;
|
|
46
|
+
constructor(url: string, meta?: {
|
|
47
|
+
type?: string;
|
|
48
|
+
size?: number;
|
|
49
|
+
name?: string;
|
|
50
|
+
} | undefined);
|
|
51
|
+
load(): Promise<Blob>;
|
|
52
|
+
pipe(fn: IRPCFilePipe): IRPCFileUnpipe;
|
|
53
|
+
then<TResult1 = Blob, TResult2 = never>(onfulfilled?: ((value: Blob) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
54
|
+
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<Blob | TResult>;
|
|
55
|
+
}
|
|
29
56
|
declare class IRPCFileStream extends IRPCFile {
|
|
30
57
|
private pipes;
|
|
31
58
|
private buffer;
|
|
@@ -34,4 +61,4 @@ declare class IRPCFileStream extends IRPCFile {
|
|
|
34
61
|
pipe(fn: IRPCFilePipe): IRPCFileUnpipe;
|
|
35
62
|
}
|
|
36
63
|
//#endregion
|
|
37
|
-
export { IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe };
|
|
64
|
+
export { IRPCBlob, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe };
|
package/dist/file.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IRPC_FILE_STATUS } from "./enum.js";
|
|
1
|
+
import { IRPC_FILE_STATUS, IRPC_STATUS } from "./enum.js";
|
|
2
2
|
import { IRPC_STORE } from "./store.js";
|
|
3
|
-
import { mutable } from "@anchorlib/core";
|
|
3
|
+
import { mutable, onCleanup } from "@anchorlib/core";
|
|
4
4
|
|
|
5
5
|
//#region src/file.ts
|
|
6
6
|
var IRPCFile = class {
|
|
@@ -33,6 +33,92 @@ var IRPCFile = class {
|
|
|
33
33
|
this.state.status = data ? IRPC_FILE_STATUS.SUCCESS : IRPC_FILE_STATUS.PENDING;
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
|
+
var IRPCBlob = class {
|
|
37
|
+
state = mutable({
|
|
38
|
+
status: IRPC_FILE_STATUS.PENDING,
|
|
39
|
+
downloaded: 0
|
|
40
|
+
});
|
|
41
|
+
data;
|
|
42
|
+
pipes = /* @__PURE__ */ new Set();
|
|
43
|
+
promise;
|
|
44
|
+
controller;
|
|
45
|
+
get status() {
|
|
46
|
+
return this.state.status;
|
|
47
|
+
}
|
|
48
|
+
get error() {
|
|
49
|
+
return this.state.error;
|
|
50
|
+
}
|
|
51
|
+
get downloaded() {
|
|
52
|
+
return this.state.downloaded;
|
|
53
|
+
}
|
|
54
|
+
get success() {
|
|
55
|
+
return this.status === IRPC_FILE_STATUS.SUCCESS;
|
|
56
|
+
}
|
|
57
|
+
get completed() {
|
|
58
|
+
return [IRPC_FILE_STATUS.SUCCESS, IRPC_FILE_STATUS.ERROR].includes(this.status);
|
|
59
|
+
}
|
|
60
|
+
constructor(url, meta) {
|
|
61
|
+
this.url = url;
|
|
62
|
+
this.meta = meta;
|
|
63
|
+
this.data = new Blob([], { type: meta?.type ?? "" });
|
|
64
|
+
}
|
|
65
|
+
load() {
|
|
66
|
+
if (this.promise) return this.promise;
|
|
67
|
+
this.controller = new AbortController();
|
|
68
|
+
this.state.status = IRPC_FILE_STATUS.PENDING;
|
|
69
|
+
this.promise = fetch(this.url, { signal: this.controller.signal }).then(async (response) => {
|
|
70
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
71
|
+
if (response.body && this.meta?.size) {
|
|
72
|
+
const reader = response.body.getReader();
|
|
73
|
+
const chunks = [];
|
|
74
|
+
let downloaded = 0;
|
|
75
|
+
while (true) {
|
|
76
|
+
const { done, value } = await reader.read();
|
|
77
|
+
if (done) break;
|
|
78
|
+
if (value) {
|
|
79
|
+
chunks.push(value);
|
|
80
|
+
downloaded += value.byteLength;
|
|
81
|
+
this.state.downloaded = downloaded;
|
|
82
|
+
this.pipes.forEach((fn) => {
|
|
83
|
+
try {
|
|
84
|
+
fn(value);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
IRPC_STORE.error(error, [{ url: this.url }]);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
this.data = new Blob(chunks, { type: this.meta?.type ?? "" });
|
|
92
|
+
} else {
|
|
93
|
+
this.data = await response.blob();
|
|
94
|
+
this.state.downloaded = this.data.size;
|
|
95
|
+
}
|
|
96
|
+
this.state.status = IRPC_FILE_STATUS.SUCCESS;
|
|
97
|
+
return this.data;
|
|
98
|
+
}).catch((error) => {
|
|
99
|
+
IRPC_STORE.error(error, [{ url: this.url }]);
|
|
100
|
+
this.state.error = error;
|
|
101
|
+
/* v8 ignore next */
|
|
102
|
+
this.state.status = this.controller?.signal?.aborted ? IRPC_STATUS.ABORTED : IRPC_FILE_STATUS.ERROR;
|
|
103
|
+
throw error;
|
|
104
|
+
});
|
|
105
|
+
onCleanup(() => {
|
|
106
|
+
/* v8 ignore next */
|
|
107
|
+
this.controller?.abort();
|
|
108
|
+
});
|
|
109
|
+
return this.promise;
|
|
110
|
+
}
|
|
111
|
+
pipe(fn) {
|
|
112
|
+
this.pipes.add(fn);
|
|
113
|
+
return () => this.pipes.delete(fn);
|
|
114
|
+
}
|
|
115
|
+
then(onfulfilled, onrejected) {
|
|
116
|
+
return this.load().then(onfulfilled, onrejected);
|
|
117
|
+
}
|
|
118
|
+
catch(onrejected) {
|
|
119
|
+
return this.load().catch(onrejected);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
36
122
|
var IRPCFileStream = class extends IRPCFile {
|
|
37
123
|
pipes = /* @__PURE__ */ new Set();
|
|
38
124
|
buffer;
|
|
@@ -83,4 +169,4 @@ var IRPCFileStream = class extends IRPCFile {
|
|
|
83
169
|
};
|
|
84
170
|
|
|
85
171
|
//#endregion
|
|
86
|
-
export { IRPCFile, IRPCFileStream };
|
|
172
|
+
export { IRPCBlob, IRPCFile, IRPCFileStream };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IRPC_BASE_CONTEXT, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT } from "./enum.js";
|
|
2
|
-
import { IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe } from "./file.js";
|
|
3
|
-
import { IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_FILE_IDENTIFIER, PacketStream, decode, encode, isFilePointer } from "./packet.js";
|
|
2
|
+
import { IRPCBlob, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe } from "./file.js";
|
|
3
|
+
import { IRPCBlobPointer, IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_BLOB_IDENTIFIER, IRPC_FILE_IDENTIFIER, PacketStream, decode, decodeBlobs, encode, encodeBlobs, isBlobPointer, isFilePointer } from "./packet.js";
|
|
4
4
|
import { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, IRPCCall } from "./call.js";
|
|
5
5
|
import { IRPCTransport } from "./transport.js";
|
|
6
6
|
import { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCCrudField, IRPCCrudMeta, IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDataSchema, IRPCDeclareConfig, IRPCDeclareInit, IRPCDefined, IRPCDriver, IRPCEntityId, IRPCFunction, IRPCHandler, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCRequests, IRPCResponse, IRPCReturnOf, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig } from "./types.js";
|
|
@@ -17,4 +17,4 @@ import { IRPCHook, IRPCRouter } from "./router.js";
|
|
|
17
17
|
import { IRPCStream } from "./stream.js";
|
|
18
18
|
import { IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPC_STORE } from "./store.js";
|
|
19
19
|
import { plan } from "@anchorlib/core";
|
|
20
|
-
export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCAdapter, IRPCArraySchema, IRPCCacheEntry, IRPCCacher, IRPCCall, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCCrudField, IRPCCrudMeta, IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDataSchema, IRPCDeclareConfig, IRPCDeclareInit, IRPCDefined, IRPCDriver, IRPCEntityId, IRPCError, IRPCErrorType, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFilePointer, IRPCFileQueue, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe, IRPCFunction, IRPCHandler, IRPCHook, IRPCHookArgs, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackage, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketJson, IRPCPacketQueues, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCReader, IRPCRequest, IRPCRequests, IRPCResolver, IRPCResponse, IRPCReturnOf, IRPCRouter, IRPCSchema, IRPCSpec, IRPCSpecHook, IRPCSpecStore, IRPCStatus, IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPCStream, IRPCStreamInit, IRPCStub, IRPCStubStore, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, PacketStream, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StreamCleanup, StreamConstructor, StubError, TRANSPORT_ERROR, TransportConfig, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
|
|
20
|
+
export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCAdapter, IRPCArraySchema, IRPCBlob, IRPCBlobPointer, IRPCCacheEntry, IRPCCacher, IRPCCall, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCCrudField, IRPCCrudMeta, IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDataSchema, IRPCDeclareConfig, IRPCDeclareInit, IRPCDefined, IRPCDriver, IRPCEntityId, IRPCError, IRPCErrorType, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFilePointer, IRPCFileQueue, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe, IRPCFunction, IRPCHandler, IRPCHook, IRPCHookArgs, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackage, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketJson, IRPCPacketQueues, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCReader, IRPCRequest, IRPCRequests, IRPCResolver, IRPCResponse, IRPCReturnOf, IRPCRouter, IRPCSchema, IRPCSpec, IRPCSpecHook, IRPCSpecStore, IRPCStatus, IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPCStream, IRPCStreamInit, IRPCStub, IRPCStubStore, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_BLOB_IDENTIFIER, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, PacketStream, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StreamCleanup, StreamConstructor, StubError, TRANSPORT_ERROR, TransportConfig, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, decodeBlobs, encode, encodeBlobs, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isBlobPointer, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
|
package/dist/index.js
CHANGED
|
@@ -8,14 +8,14 @@ import { IRPCReader } from "./reader.js";
|
|
|
8
8
|
import { IRPCTransport } from "./transport.js";
|
|
9
9
|
import { IRPCPackage, createPackage, intercept } from "./module.js";
|
|
10
10
|
import { IRPCRouter } from "./router.js";
|
|
11
|
+
import { IRPCBlob, IRPCFile, IRPCFileStream } from "./file.js";
|
|
12
|
+
import { IRPC_BLOB_IDENTIFIER, IRPC_FILE_IDENTIFIER, decode, decodeBlobs, encode, encodeBlobs, isBlobPointer, isFilePointer } from "./packet.js";
|
|
11
13
|
import { IRPCStream } from "./stream.js";
|
|
12
14
|
import { IRPCStore, IRPC_STORE } from "./store.js";
|
|
13
15
|
import { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, IRPCCall } from "./call.js";
|
|
14
16
|
import { createCredentials, credential, getCredentials } from "./credential.js";
|
|
15
|
-
import { IRPCFile, IRPCFileStream } from "./file.js";
|
|
16
|
-
import { IRPC_FILE_IDENTIFIER, decode, encode, isFilePointer } from "./packet.js";
|
|
17
17
|
import { IRPCResolver } from "./resolver.js";
|
|
18
18
|
import { IRPCDriver } from "./types.js";
|
|
19
19
|
import { plan } from "@anchorlib/core";
|
|
20
20
|
|
|
21
|
-
export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCAdapter, IRPCCacher, IRPCCall, IRPCDriver, IRPCError, IRPCFile, IRPCFileStream, IRPCPackage, IRPCReader, IRPCResolver, IRPCRouter, IRPCStore, IRPCStream, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
|
|
21
|
+
export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCAdapter, IRPCBlob, IRPCCacher, IRPCCall, IRPCDriver, IRPCError, IRPCFile, IRPCFileStream, IRPCPackage, IRPCReader, IRPCResolver, IRPCRouter, IRPCStore, IRPCStream, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_BLOB_IDENTIFIER, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, decodeBlobs, encode, encodeBlobs, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isBlobPointer, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
|
package/dist/module.js
CHANGED
|
@@ -132,7 +132,7 @@ var IRPCPackage = class {
|
|
|
132
132
|
* @returns {IRPCReader<IRPCData>} - The reader for the call.
|
|
133
133
|
*/
|
|
134
134
|
function prepare(getArgs, deferred, debounce = 0) {
|
|
135
|
-
const reader = new IRPCReader(uuid(), spec.seed(), deferred ? IRPC_STATUS.IDLE : IRPC_STATUS.PENDING);
|
|
135
|
+
const reader = new IRPCReader(uuid(), spec.seed(), deferred ? IRPC_STATUS.IDLE : IRPC_STATUS.PENDING, true);
|
|
136
136
|
if (isBrowser()) {
|
|
137
137
|
const observer = createObserver(() => {
|
|
138
138
|
observer.reset();
|
|
@@ -143,6 +143,8 @@ var IRPCPackage = class {
|
|
|
143
143
|
const args = observer.run(getArgs);
|
|
144
144
|
if (!coalesce) return execute(args, reader);
|
|
145
145
|
schedule(() => {
|
|
146
|
+
if (reader.status === IRPC_STATUS.PENDING) reader.close();
|
|
147
|
+
reader.resume();
|
|
146
148
|
execute(args, reader);
|
|
147
149
|
});
|
|
148
150
|
};
|
package/dist/packet.d.ts
CHANGED
|
@@ -3,11 +3,21 @@ import { IRPCData } from "./types.js";
|
|
|
3
3
|
|
|
4
4
|
//#region src/packet.d.ts
|
|
5
5
|
declare const IRPC_FILE_IDENTIFIER: "IRPC_PACKET_FILE";
|
|
6
|
+
declare const IRPC_BLOB_IDENTIFIER: "IRPC_PACKET_BLOB";
|
|
6
7
|
type IRPCFilePointer = {
|
|
7
8
|
id: string;
|
|
8
9
|
type: typeof IRPC_FILE_IDENTIFIER;
|
|
9
10
|
meta: IRPCFileMeta;
|
|
10
11
|
};
|
|
12
|
+
type IRPCBlobPointer = {
|
|
13
|
+
type: typeof IRPC_BLOB_IDENTIFIER;
|
|
14
|
+
url: string;
|
|
15
|
+
meta?: {
|
|
16
|
+
type?: string;
|
|
17
|
+
size?: number;
|
|
18
|
+
name?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
11
21
|
type IRPCFileQueue = {
|
|
12
22
|
file: IRPCFilePointer;
|
|
13
23
|
data: Blob;
|
|
@@ -26,7 +36,25 @@ type PacketStream = {
|
|
|
26
36
|
resolved: number;
|
|
27
37
|
};
|
|
28
38
|
declare function isFilePointer(data: IRPCData): boolean;
|
|
39
|
+
declare function isBlobPointer(data: IRPCData): boolean;
|
|
29
40
|
declare function encode(data: IRPCData): IRPCPacketQueues;
|
|
30
41
|
declare function decode(packet: IRPCPacketJson): PacketStream;
|
|
42
|
+
/**
|
|
43
|
+
* Recursively replaces all IRPCBlobPointer objects in a data tree with IRPCBlob instances.
|
|
44
|
+
* Used by client-side transports to materialize blob references after receiving response data.
|
|
45
|
+
* Eagerly calls .load() to kick off the fetch — the caller awaits the thenable to get the loaded blob.
|
|
46
|
+
*
|
|
47
|
+
* @param data - The data tree potentially containing IRPCBlobPointer objects.
|
|
48
|
+
* @returns The data tree with blob pointers replaced by IRPCBlob instances.
|
|
49
|
+
*/
|
|
50
|
+
declare function decodeBlobs<T>(data: unknown): T;
|
|
51
|
+
/**
|
|
52
|
+
* Recursively replaces all IRPCBlob instances in a data tree with IRPCBlobPointer objects.
|
|
53
|
+
* Used by IRPCStream to encode blobs before packets are JSON-serialized for transport.
|
|
54
|
+
*
|
|
55
|
+
* @param data - The data tree potentially containing IRPCBlob instances.
|
|
56
|
+
* @returns A new data tree with IRPCBlob instances replaced by IRPCBlobPointer objects.
|
|
57
|
+
*/
|
|
58
|
+
declare function encodeBlobs(data: unknown): unknown;
|
|
31
59
|
//#endregion
|
|
32
|
-
export { IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_FILE_IDENTIFIER, PacketStream, decode, encode, isFilePointer };
|
|
60
|
+
export { IRPCBlobPointer, IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_BLOB_IDENTIFIER, IRPC_FILE_IDENTIFIER, PacketStream, decode, decodeBlobs, encode, encodeBlobs, isBlobPointer, isFilePointer };
|
package/dist/packet.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { IRPCFile, IRPCFileStream } from "./file.js";
|
|
1
|
+
import { IRPCBlob, IRPCFile, IRPCFileStream } from "./file.js";
|
|
2
2
|
import { isArray, isObject, uuid } from "@anchorlib/core";
|
|
3
3
|
|
|
4
4
|
//#region src/packet.ts
|
|
5
5
|
const IRPC_FILE_IDENTIFIER = "IRPC_PACKET_FILE";
|
|
6
|
+
const IRPC_BLOB_IDENTIFIER = "IRPC_PACKET_BLOB";
|
|
6
7
|
function isFilePointer(data) {
|
|
7
8
|
return isObject(data) && data.type === IRPC_FILE_IDENTIFIER;
|
|
8
9
|
}
|
|
10
|
+
function isBlobPointer(data) {
|
|
11
|
+
return isObject(data) && data.type === IRPC_BLOB_IDENTIFIER;
|
|
12
|
+
}
|
|
9
13
|
function encode(data) {
|
|
10
14
|
const json = {
|
|
11
15
|
data,
|
|
@@ -15,7 +19,8 @@ function encode(data) {
|
|
|
15
19
|
json,
|
|
16
20
|
queues: []
|
|
17
21
|
};
|
|
18
|
-
if (data instanceof
|
|
22
|
+
if (data instanceof IRPCBlob) json.data = createBlobPointer(data);
|
|
23
|
+
else if (data instanceof IRPCFile) {
|
|
19
24
|
const { pointer, queue } = createPointer(data);
|
|
20
25
|
json.data = pointer;
|
|
21
26
|
json.files.push(pointer);
|
|
@@ -52,6 +57,13 @@ function createPointer(file) {
|
|
|
52
57
|
}
|
|
53
58
|
};
|
|
54
59
|
}
|
|
60
|
+
function createBlobPointer(blob) {
|
|
61
|
+
return {
|
|
62
|
+
type: IRPC_BLOB_IDENTIFIER,
|
|
63
|
+
url: blob.url,
|
|
64
|
+
meta: blob.meta
|
|
65
|
+
};
|
|
66
|
+
}
|
|
55
67
|
/**
|
|
56
68
|
* Replace all IRPCFile inside an object with IRPCPacketFile.
|
|
57
69
|
* @param {Record<string, unknown> | unknown[]} data - The object to encode.
|
|
@@ -60,7 +72,8 @@ function createPointer(file) {
|
|
|
60
72
|
*/
|
|
61
73
|
function encodePointers(data, pointers, queues) {
|
|
62
74
|
if (isArray(data)) data.forEach((item, i) => {
|
|
63
|
-
if (item instanceof
|
|
75
|
+
if (item instanceof IRPCBlob) data[i] = createBlobPointer(item);
|
|
76
|
+
else if (item instanceof IRPCFile) {
|
|
64
77
|
const { pointer, queue } = createPointer(item);
|
|
65
78
|
data[i] = pointer;
|
|
66
79
|
pointers.push(pointer);
|
|
@@ -68,7 +81,8 @@ function encodePointers(data, pointers, queues) {
|
|
|
68
81
|
} else if (isObject(item) || isArray(item)) encodePointers(item, pointers, queues);
|
|
69
82
|
});
|
|
70
83
|
else if (isObject(data)) Object.entries(data).forEach(([key, value]) => {
|
|
71
|
-
if (value instanceof
|
|
84
|
+
if (value instanceof IRPCBlob) data[key] = createBlobPointer(value);
|
|
85
|
+
else if (value instanceof IRPCFile) {
|
|
72
86
|
const { pointer, queue } = createPointer(value);
|
|
73
87
|
data[key] = pointer;
|
|
74
88
|
pointers.push(pointer);
|
|
@@ -95,6 +109,41 @@ function decodePointers(data, files) {
|
|
|
95
109
|
} else if (isObject(value) || isArray(value)) decodePointers(value, files);
|
|
96
110
|
});
|
|
97
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Recursively replaces all IRPCBlobPointer objects in a data tree with IRPCBlob instances.
|
|
114
|
+
* Used by client-side transports to materialize blob references after receiving response data.
|
|
115
|
+
* Eagerly calls .load() to kick off the fetch — the caller awaits the thenable to get the loaded blob.
|
|
116
|
+
*
|
|
117
|
+
* @param data - The data tree potentially containing IRPCBlobPointer objects.
|
|
118
|
+
* @returns The data tree with blob pointers replaced by IRPCBlob instances.
|
|
119
|
+
*/
|
|
120
|
+
function decodeBlobs(data) {
|
|
121
|
+
if (!data || typeof data !== "object") return data;
|
|
122
|
+
if (isBlobPointer(data)) {
|
|
123
|
+
const pointer = data;
|
|
124
|
+
const blob = new IRPCBlob(pointer.url, pointer.meta);
|
|
125
|
+
blob.load();
|
|
126
|
+
return blob;
|
|
127
|
+
}
|
|
128
|
+
if (Array.isArray(data)) for (let i = 0; i < data.length; i++) data[i] = decodeBlobs(data[i]);
|
|
129
|
+
else for (const [key, value] of Object.entries(data)) data[key] = decodeBlobs(value);
|
|
130
|
+
return data;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Recursively replaces all IRPCBlob instances in a data tree with IRPCBlobPointer objects.
|
|
134
|
+
* Used by IRPCStream to encode blobs before packets are JSON-serialized for transport.
|
|
135
|
+
*
|
|
136
|
+
* @param data - The data tree potentially containing IRPCBlob instances.
|
|
137
|
+
* @returns A new data tree with IRPCBlob instances replaced by IRPCBlobPointer objects.
|
|
138
|
+
*/
|
|
139
|
+
function encodeBlobs(data) {
|
|
140
|
+
if (data instanceof IRPCBlob) return createBlobPointer(data);
|
|
141
|
+
if (!data || typeof data !== "object") return data;
|
|
142
|
+
if (Array.isArray(data)) return data.map((item) => encodeBlobs(item));
|
|
143
|
+
const result = {};
|
|
144
|
+
for (const [key, value] of Object.entries(data)) result[key] = encodeBlobs(value);
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
98
147
|
|
|
99
148
|
//#endregion
|
|
100
|
-
export { IRPC_FILE_IDENTIFIER, decode, encode, isFilePointer };
|
|
149
|
+
export { IRPC_BLOB_IDENTIFIER, IRPC_FILE_IDENTIFIER, decode, decodeBlobs, encode, encodeBlobs, isBlobPointer, isFilePointer };
|
package/dist/stream.js
CHANGED
|
@@ -2,6 +2,7 @@ import { CallError, HandlerError, ResolveError } from "./error.js";
|
|
|
2
2
|
import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
|
|
3
3
|
import { getAbortController, getAbortSignal } from "./context.js";
|
|
4
4
|
import { RemoteState } from "./state.js";
|
|
5
|
+
import { encodeBlobs } from "./packet.js";
|
|
5
6
|
import { IRPC_STORE } from "./store.js";
|
|
6
7
|
|
|
7
8
|
//#region src/stream.ts
|
|
@@ -65,7 +66,7 @@ var IRPCStream = class {
|
|
|
65
66
|
}
|
|
66
67
|
const { result } = response;
|
|
67
68
|
if (result instanceof RemoteState) {
|
|
68
|
-
this.value = result.data;
|
|
69
|
+
this.value = encodeBlobs(result.data);
|
|
69
70
|
if (result.status === IRPC_STATUS.SUCCESS || result.status === IRPC_STATUS.ERROR) {
|
|
70
71
|
if (result.status === IRPC_STATUS.ERROR) {
|
|
71
72
|
this.error = HandlerError.failed(result.error).json();
|
|
@@ -90,7 +91,7 @@ var IRPCStream = class {
|
|
|
90
91
|
id,
|
|
91
92
|
name,
|
|
92
93
|
type: IRPC_PACKET_TYPE.ANSWER,
|
|
93
|
-
data: result.data,
|
|
94
|
+
data: encodeBlobs(result.data),
|
|
94
95
|
status: result.status,
|
|
95
96
|
createdAt: Date.now()
|
|
96
97
|
});
|
|
@@ -105,7 +106,7 @@ var IRPCStream = class {
|
|
|
105
106
|
data: {
|
|
106
107
|
type,
|
|
107
108
|
keys,
|
|
108
|
-
value
|
|
109
|
+
value: encodeBlobs(value)
|
|
109
110
|
},
|
|
110
111
|
type: IRPC_PACKET_TYPE.EVENT,
|
|
111
112
|
status: state.status,
|
|
@@ -140,7 +141,7 @@ var IRPCStream = class {
|
|
|
140
141
|
};
|
|
141
142
|
abortSignal?.addEventListener("abort", abortStream, { once: true });
|
|
142
143
|
} else {
|
|
143
|
-
this.value = result;
|
|
144
|
+
this.value = encodeBlobs(result);
|
|
144
145
|
if (response.error) {
|
|
145
146
|
this.error = response.error;
|
|
146
147
|
this.status = IRPC_STATUS.ERROR;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
|
|
2
|
-
import { IRPCFile } from "./file.js";
|
|
2
|
+
import { IRPCBlob, IRPCFile } from "./file.js";
|
|
3
3
|
import { IRPCFilePointer } from "./packet.js";
|
|
4
4
|
import { IRPCTransport } from "./transport.js";
|
|
5
5
|
import { RemoteState } from "./state.js";
|
|
@@ -114,12 +114,12 @@ type IRPCObject = {
|
|
|
114
114
|
* Represents all possible data types in IRPC, including primitives, objects, and arrays.
|
|
115
115
|
* This is a recursive type that allows nested structures.
|
|
116
116
|
*/
|
|
117
|
-
type IRPCData = IRPCPrimitive | IRPCObject | IRPCFile | IRPCData[];
|
|
117
|
+
type IRPCData = IRPCPrimitive | IRPCObject | IRPCFile | IRPCBlob | IRPCData[];
|
|
118
118
|
/**
|
|
119
119
|
* Represents all possible defined data types in IRPC, including primitives, objects, and arrays.
|
|
120
120
|
* This is a recursive type that allows nested structures.
|
|
121
121
|
*/
|
|
122
|
-
type IRPCDefined = string | number | boolean | IRPCObject | IRPCFile | IRPCDefined[];
|
|
122
|
+
type IRPCDefined = string | number | boolean | IRPCObject | IRPCFile | IRPCBlob | IRPCDefined[];
|
|
123
123
|
/**
|
|
124
124
|
* Union type of all primitive Zod schema types used for validation.
|
|
125
125
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@irpclib/irpc",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"zod": "^4.1.5"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@anchorlib/core": "1.2.
|
|
39
|
+
"@anchorlib/core": "1.2.2",
|
|
40
40
|
"typescript": "^5.9.3"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|