@livequery/rpc 2.0.101 → 2.0.104
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 +60 -1
- package/dist/ExtensionChannel.d.ts +7 -0
- package/dist/ExtensionChannel.d.ts.map +1 -0
- package/dist/ExtensionChannel.js +62 -0
- package/dist/ExtensionChannel.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @livequery/rpc
|
|
2
2
|
|
|
3
|
-
Lightweight RxJS-based RPC utilities for exposing services from a `SharedWorker` and consuming them from the main thread with typed proxies.
|
|
3
|
+
Lightweight RxJS-based RPC utilities for exposing services from a `SharedWorker` or an extension background runtime and consuming them from the main thread with typed proxies.
|
|
4
4
|
|
|
5
5
|
## AI Agent Notes
|
|
6
6
|
|
|
@@ -29,6 +29,7 @@ bun add @livequery/rpc rxjs
|
|
|
29
29
|
## What It Exports
|
|
30
30
|
|
|
31
31
|
```ts
|
|
32
|
+
export * from "./ExtensionChannel"
|
|
32
33
|
export * from "./RpcChannel"
|
|
33
34
|
export * from "./SharedWorkerChannel"
|
|
34
35
|
export * from "./ServiceLinker"
|
|
@@ -49,6 +50,41 @@ ServiceLinker --(RpcMessage)--> SharedWorkerChannel --> WorkerManager --> your s
|
|
|
49
50
|
|--------------------(response stream)-----------------------|
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
For extension Manifest V3, the same flow can run over `ExtensionChannel` and `chrome.runtime` messaging instead of `SharedWorker`.
|
|
54
|
+
|
|
55
|
+
## Extension MV3 Example
|
|
56
|
+
|
|
57
|
+
### Background service worker
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { ExtensionChannel, WorkerManager } from "@livequery/rpc"
|
|
61
|
+
import { CounterService } from "./CounterService"
|
|
62
|
+
|
|
63
|
+
const channel = new ExtensionChannel()
|
|
64
|
+
const manager = new WorkerManager(channel)
|
|
65
|
+
|
|
66
|
+
manager.exposeService("counter", new CounterService())
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Popup, options page, or content script
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { ExtensionChannel, ServiceLinker, type WorkerService } from "@livequery/rpc"
|
|
73
|
+
import type { CounterService } from "./CounterService"
|
|
74
|
+
|
|
75
|
+
const channel = new ExtensionChannel()
|
|
76
|
+
const linker = new ServiceLinker(channel)
|
|
77
|
+
|
|
78
|
+
const counter = linker.linkService<WorkerService<CounterService>>("counter")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`ExtensionChannel` auto-detects its context at construction time:
|
|
82
|
+
|
|
83
|
+
- **Background service worker** (`typeof window === 'undefined'`): listens on `chrome.runtime.onMessage` and routes responses back to the originating tab via `chrome.tabs.sendMessage`, or falls back to `chrome.runtime.sendMessage` when the message did not originate from a tab.
|
|
84
|
+
- **Foreground context** (popup, options page, content script): listens on `chrome.runtime.onMessage` for responses arriving from the background and sends requests with `chrome.runtime.sendMessage`.
|
|
85
|
+
|
|
86
|
+
If `chrome` is not available (e.g. during SSR), all operations silently no-op.
|
|
87
|
+
|
|
52
88
|
## When To Use This Package
|
|
53
89
|
|
|
54
90
|
Use it when you want to:
|
|
@@ -275,6 +311,29 @@ const worker = new SharedWorker(new URL("./worker.ts", import.meta.url), { type:
|
|
|
275
311
|
const channel = new SharedWorkerChannel(worker)
|
|
276
312
|
```
|
|
277
313
|
|
|
314
|
+
### `ExtensionChannel`
|
|
315
|
+
|
|
316
|
+
Concrete `RpcChannel` implementation for Chrome extension Manifest V3 messaging.
|
|
317
|
+
|
|
318
|
+
Auto-detects its context at construction time — no argument is required.
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
const channel = new ExtensionChannel()
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Background service worker** (`typeof window === 'undefined'`):
|
|
325
|
+
|
|
326
|
+
- listens on `chrome.runtime.onMessage`
|
|
327
|
+
- responds to tab-originated messages via `chrome.tabs.sendMessage(tabId, …)`
|
|
328
|
+
- responds to non-tab messages via `chrome.runtime.sendMessage(…)`
|
|
329
|
+
|
|
330
|
+
**Foreground context** (popup, options page, content script):
|
|
331
|
+
|
|
332
|
+
- listens on `chrome.runtime.onMessage` for responses from the background
|
|
333
|
+
- sends requests with `chrome.runtime.sendMessage`
|
|
334
|
+
|
|
335
|
+
If `chrome` is unavailable (e.g. during SSR), all operations silently no-op.
|
|
336
|
+
|
|
278
337
|
### `WorkerManager`
|
|
279
338
|
|
|
280
339
|
Registers named services and routes incoming RPC requests.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtensionChannel.d.ts","sourceRoot":"","sources":["../src/ExtensionChannel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAyB7D,qBAAa,gBAAiB,SAAQ,UAAU;;;IAmD5C,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;CAIlC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { RpcChannel } from "./RpcChannel.js";
|
|
2
|
+
const chrome = globalThis.chrome;
|
|
3
|
+
function isRpcMessage(value) {
|
|
4
|
+
return !!value && typeof value === "object" && "id" in value;
|
|
5
|
+
}
|
|
6
|
+
export class ExtensionChannel extends RpcChannel {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
if (typeof window == 'undefined') {
|
|
10
|
+
this.#initBackground();
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
this.#initForegound();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
#initForegound() {
|
|
17
|
+
if (!chrome)
|
|
18
|
+
return;
|
|
19
|
+
const runtime = chrome.runtime;
|
|
20
|
+
runtime?.onMessage.addListener((message, sender, sendResponse) => {
|
|
21
|
+
if (!isRpcMessage(message))
|
|
22
|
+
return;
|
|
23
|
+
const respond = (response) => {
|
|
24
|
+
runtime?.sendMessage({
|
|
25
|
+
id: message.id,
|
|
26
|
+
response
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
this.next({ ...message, respond });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
#initBackground() {
|
|
33
|
+
if (!chrome)
|
|
34
|
+
return;
|
|
35
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
36
|
+
if (!isRpcMessage(message))
|
|
37
|
+
return;
|
|
38
|
+
const tabId = sender.tab?.id;
|
|
39
|
+
const respond = (response) => {
|
|
40
|
+
if (tabId) {
|
|
41
|
+
chrome.tabs.sendMessage(tabId, {
|
|
42
|
+
id: message.id,
|
|
43
|
+
response
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
chrome.runtime.sendMessage({
|
|
48
|
+
id: message.id,
|
|
49
|
+
response
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
this.next({ ...message, respond });
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
send(message) {
|
|
57
|
+
if (!chrome)
|
|
58
|
+
return;
|
|
59
|
+
chrome.runtime.sendMessage(message);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=ExtensionChannel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtensionChannel.js","sourceRoot":"","sources":["../src/ExtensionChannel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,iBAAiB,CAAA;AAY7D,MAAM,MAAM,GAAI,UAOd,CAAC,MAAM,CAAA;AAET,SAAS,YAAY,CAAC,KAAc;IAChC,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAA;AAChE,CAAC;AAED,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAI5C;QACI,KAAK,EAAE,CAAA;QACP,IAAI,OAAO,MAAM,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,EAAE,CAAA;QAC1B,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,cAAc,EAAE,CAAA;QACzB,CAAC;IACL,CAAC;IAED,cAAc;QACV,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAC9B,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;YAC7D,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;gBAAE,OAAM;YAClC,MAAM,OAAO,GAAG,CAAC,QAAgC,EAAE,EAAE;gBACjD,OAAO,EAAE,WAAW,CAAC;oBACjB,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,QAAQ;iBACU,CAAC,CAAA;YAC3B,CAAC,CAAA;YACD,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QACtC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,eAAe;QACX,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;YACnE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;gBAAE,OAAM;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,EAAE,EAAE,CAAA;YAC5B,MAAM,OAAO,GAAG,CAAC,QAAgC,EAAE,EAAE;gBACjD,IAAI,KAAK,EAAE,CAAC;oBACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;wBAC3B,EAAE,EAAE,OAAO,CAAC,EAAE;wBACd,QAAQ;qBACU,CAAC,CAAA;gBAC3B,CAAC;qBAAM,CAAC;oBACJ,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;wBACvB,EAAE,EAAE,OAAO,CAAC,EAAE;wBACd,QAAQ;qBACU,CAAC,CAAA;gBAC3B,CAAC;YACL,CAAC,CAAA;YACD,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QACtC,CAAC,CAAC,CAAC;IACP,CAAC;IAGD,IAAI,CAAC,OAAmB;QACpB,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;CACJ"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gBAAgB,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gBAAgB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livequery/rpc",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.104",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
"import": "./dist/index.js",
|
|
22
22
|
"default": "./dist/index.js"
|
|
23
23
|
},
|
|
24
|
+
"./ExtensionChannel": {
|
|
25
|
+
"types": "./dist/ExtensionChannel.d.ts",
|
|
26
|
+
"import": "./dist/ExtensionChannel.js",
|
|
27
|
+
"default": "./dist/ExtensionChannel.js"
|
|
28
|
+
},
|
|
24
29
|
"./RpcChannel": {
|
|
25
30
|
"types": "./dist/RpcChannel.d.ts",
|
|
26
31
|
"import": "./dist/RpcChannel.js",
|