Experiment to rebuild Diffuse using web applets.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: switch out rpc lib for comlink

+59 -44
+2 -1
deno.lock
··· 25 25 "npm:@automerge/automerge@^3.0.0-beta.0", 26 26 "npm:@js-temporal/polyfill@~0.5.1", 27 27 "npm:@jsr/bradenmacdonald__s3-lite-client@0.9", 28 + "npm:@jsr/okikio__transferables@^1.0.2", 28 29 "npm:@jsr/std__media-types@^1.1.0", 29 30 "npm:@okikio/sharedworker@^1.1.0", 30 31 "npm:@orama/orama@^3.1.7", 31 32 "npm:@orama/plugin-qps@^3.1.7", 32 33 "npm:@phosphor-icons/web@^2.1.2", 33 34 "npm:@picocss/pico@^2.1.1", 34 - "npm:@remote-ui/rpc@^1.4.7", 35 35 "npm:@tokenizer/http@~0.9.2", 36 36 "npm:@tokenizer/range@0.13", 37 37 "npm:@types/throttle-debounce@^5.0.2", ··· 39 39 "npm:astro-purgecss@^5.2.2", 40 40 "npm:astro-scope@^3.0.1", 41 41 "npm:astro@^5.7.4", 42 + "npm:comlink@^4.4.2", 42 43 "npm:fast-average-color@^9.5.0", 43 44 "npm:iconoir@^7.11.0", 44 45 "npm:idb-keyval@^6.2.1",
+14 -7
package-lock.json
··· 9 9 "@bradenmacdonald/s3-lite-client": "npm:@jsr/bradenmacdonald__s3-lite-client@^0.9.0", 10 10 "@js-temporal/polyfill": "^0.5.1", 11 11 "@okikio/sharedworker": "^1.1.0", 12 + "@okikio/transferables": "npm:@jsr/okikio__transferables@^1.0.2", 12 13 "@orama/orama": "^3.1.7", 13 14 "@orama/plugin-qps": "^3.1.7", 14 15 "@phosphor-icons/web": "^2.1.2", 15 16 "@picocss/pico": "^2.1.1", 16 - "@remote-ui/rpc": "^1.4.7", 17 17 "@std/media-types": "npm:@jsr/std__media-types@^1.1.0", 18 18 "@tokenizer/http": "^0.9.2", 19 19 "@tokenizer/range": "^0.13.0", 20 20 "@web-applets/sdk": "https://gitpkg.vercel.app/unternet-co/web-applets/sdk?tokono.ma/experiment&scripts.postinstall=npm%20i%20%40types%2Fnode%20%26%26%20npx%20tsc", 21 21 "98.css": "^0.1.21", 22 + "comlink": "^4.4.2", 22 23 "fast-average-color": "^9.5.0", 23 24 "iconoir": "^7.11.0", 24 25 "idb-keyval": "^6.2.1", ··· 1138 1139 "integrity": "sha512-Xj9TUWll9mhARsKu5DtlQCjRekfJfQ2E291ow6gmXIz+WuF6uJMH8ZmGhdRTx/ndOippHnm1j/vxXNjmR6JuXw==", 1139 1140 "license": "MIT" 1140 1141 }, 1142 + "node_modules/@okikio/transferables": { 1143 + "name": "@jsr/okikio__transferables", 1144 + "version": "1.0.2", 1145 + "resolved": "https://npm.jsr.io/~/11/@jsr/okikio__transferables/1.0.2.tgz", 1146 + "integrity": "sha512-xz7RmslHsTt/Cy7GPnDurV1aKuUuVaR3FOIcKtLMuY8e+yEMVnwkPqaFWvsO/WbfeUQQnygo5C7g1/oLURrPsA==" 1147 + }, 1141 1148 "node_modules/@orama/orama": { 1142 1149 "version": "3.1.9", 1143 1150 "resolved": "https://registry.npmjs.org/@orama/orama/-/orama-3.1.9.tgz", ··· 1485 1492 "integrity": "sha512-kIDugA7Ps4U+2BHxiNHmvgPIQDWPDU4IeU6TNRdvXQM1uZX+FibqDQT2xUOnnO2yq/LUHcwnGlu1hvf4KfXnMg==", 1486 1493 "license": "MIT" 1487 1494 }, 1488 - "node_modules/@remote-ui/rpc": { 1489 - "version": "1.4.7", 1490 - "resolved": "https://registry.npmjs.org/@remote-ui/rpc/-/rpc-1.4.7.tgz", 1491 - "integrity": "sha512-ORiaKsbVBSEi3Z4YWOj5Ucrp70NrkNktI1hdqqfBW7Z3o0YoxTX9MIqtLmsc6721IbjmExvLrLip5I5Y7uAbng==", 1492 - "license": "MIT" 1493 - }, 1494 1495 "node_modules/@rollup/pluginutils": { 1495 1496 "version": "5.2.0", 1496 1497 "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", ··· 2945 2946 "color-name": "^1.0.0", 2946 2947 "simple-swizzle": "^0.2.2" 2947 2948 } 2949 + }, 2950 + "node_modules/comlink": { 2951 + "version": "4.4.2", 2952 + "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz", 2953 + "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==", 2954 + "license": "Apache-2.0" 2948 2955 }, 2949 2956 "node_modules/comma-separated-tokens": { 2950 2957 "version": "2.0.3",
+2 -1
package.json
··· 4 4 "@bradenmacdonald/s3-lite-client": "npm:@jsr/bradenmacdonald__s3-lite-client@^0.9.0", 5 5 "@js-temporal/polyfill": "^0.5.1", 6 6 "@okikio/sharedworker": "^1.1.0", 7 + "@okikio/transferables": "npm:@jsr/okikio__transferables@^1.0.2", 7 8 "@orama/orama": "^3.1.7", 8 9 "@orama/plugin-qps": "^3.1.7", 9 10 "@phosphor-icons/web": "^2.1.2", 10 11 "@picocss/pico": "^2.1.1", 11 - "@remote-ui/rpc": "^1.4.7", 12 12 "@std/media-types": "npm:@jsr/std__media-types@^1.1.0", 13 13 "@tokenizer/http": "^0.9.2", 14 14 "@tokenizer/range": "^0.13.0", 15 15 "@web-applets/sdk": "https://gitpkg.vercel.app/unternet-co/web-applets/sdk?tokono.ma/experiment&scripts.postinstall=npm%20i%20%40types%2Fnode%20%26%26%20npx%20tsc", 16 16 "98.css": "^0.1.21", 17 + "comlink": "^4.4.2", 17 18 "fast-average-color": "^9.5.0", 18 19 "iconoir": "^7.11.0", 19 20 "idb-keyval": "^6.2.1",
+2 -2
src/pages/configurator/input/_applet.astro
··· 91 91 }; 92 92 93 93 const contextualize = async (tracks: Track[]) => { 94 - const groups = await worker.call.groupTracks(tracks); 94 + const groups = await worker.groupTracks(tracks); 95 95 const promises = Object.entries(groups).map( 96 96 async ([scheme, tracksGroup]: [string, Track[]]) => { 97 97 if (!isSupportedScheme(scheme) || tracksGroup.length === 0) return; ··· 124 124 }; 125 125 126 126 const list = async (cachedTracks: Track[] = []) => { 127 - const groups = await worker.call.groupTracks(cachedTracks); 127 + const groups = await worker.groupTracks(cachedTracks); 128 128 129 129 const promises = Object.entries(groups).map( 130 130 async ([scheme, cachedTracksGroup]: [string, Track[]]) => {
+4 -4
src/pages/engine/queue/_applet.astro
··· 34 34 context.setActionHandler("unshift", unshift); 35 35 36 36 async function add(items: Track[]) { 37 - context.data = await worker.call.add(context.data, items); 37 + context.data = await worker.add(context.data, items); 38 38 } 39 39 40 40 async function pool(items: Track[]) { 41 - context.data = await worker.call.pool(context.data, items); 41 + context.data = await worker.pool(context.data, items); 42 42 } 43 43 44 44 async function shift() { 45 - context.data = await worker.call.shift(context.data); 45 + context.data = await worker.shift(context.data); 46 46 } 47 47 48 48 async function unshift() { 49 - context.data = await worker.call.unshift(context.data); 49 + context.data = await worker.unshift(context.data); 50 50 } 51 51 </script>
+5 -5
src/pages/input/native-fs/_applet.astro
··· 38 38 // ACTIONS 39 39 //////////////////////////////////////////// 40 40 const consult = async (fileUriOrScheme: string) => { 41 - return await worker.call.consult(fileUriOrScheme); 41 + return await worker.consult(fileUriOrScheme); 42 42 }; 43 43 44 44 const contextualize = async (cachedTracks: Track[]) => { 45 - return await worker.call.contextualize(cachedTracks); 45 + return await worker.contextualize(cachedTracks); 46 46 }; 47 47 48 48 const groupConsult = async (tracks: Track[]) => { 49 - return await worker.call.groupConsult(tracks); 49 + return await worker.groupConsult(tracks); 50 50 }; 51 51 52 52 const list = async (cachedTracks: Track[] = []) => { 53 - return await worker.call.list(cachedTracks); 53 + return await worker.list(cachedTracks); 54 54 }; 55 55 56 56 const resolve = async (args: { uri: string }) => { 57 - return await worker.call.resolve(args); 57 + return await worker.resolve(args); 58 58 }; 59 59 60 60 const mount = async () => {
+5 -5
src/pages/input/opensubsonic/_applet.astro
··· 39 39 // ACTIONS 40 40 //////////////////////////////////////////// 41 41 const consult = async (fileUriOrScheme: string) => { 42 - return await worker.call.consult(fileUriOrScheme); 42 + return await worker.consult(fileUriOrScheme); 43 43 }; 44 44 45 45 const contextualize = async (tracks: Track[]) => { 46 - const s = await worker.call.contextualize(tracks); 46 + const s = await worker.contextualize(tracks); 47 47 ui?.setServers({ ...ui?.servers(), ...s }); 48 48 }; 49 49 50 50 const groupConsult = async (tracks: Track[]) => { 51 - return await worker.call.groupConsult(tracks); 51 + return await worker.groupConsult(tracks); 52 52 }; 53 53 54 54 const list = async (cachedTracks: Track[] = []) => { 55 - return await worker.call.list(cachedTracks); 55 + return await worker.list(cachedTracks); 56 56 }; 57 57 58 58 const resolve = async (args: { method: string; uri: string }) => { 59 - return await worker.call.resolve(args); 59 + return await worker.resolve(args); 60 60 }; 61 61 62 62 const mount = async () => {};
+5 -5
src/pages/input/s3/_applet.astro
··· 59 59 // ACTIONS 60 60 //////////////////////////////////////////// 61 61 const consult = async (fileUriOrScheme: string) => { 62 - return await worker.call.consult(fileUriOrScheme); 62 + return await worker.consult(fileUriOrScheme); 63 63 }; 64 64 65 65 const contextualize = async (tracks: Track[]) => { 66 - const s = await worker.call.contextualize(tracks); 66 + const s = await worker.contextualize(tracks); 67 67 ui?.setBuckets({ ...ui?.buckets(), ...s }); 68 68 }; 69 69 70 70 const groupConsult = async (tracks: Track[]) => { 71 - return await worker.call.groupConsult(tracks); 71 + return await worker.groupConsult(tracks); 72 72 }; 73 73 74 74 const list = async (cachedTracks: Track[] = []) => { 75 - return await worker.call.list(cachedTracks); 75 + return await worker.list(cachedTracks); 76 76 }; 77 77 78 78 const resolve = async (args: { method: string; uri: string }) => { 79 - return await worker.call.resolve(args); 79 + return await worker.resolve(args); 80 80 }; 81 81 82 82 const mount = async () => {};
+2 -2
src/pages/output/indexed-db/_applet.astro
··· 25 25 context, 26 26 tracks: { 27 27 async get() { 28 - return worker.call.getTracks(); 28 + return worker.getTracks(); 29 29 }, 30 30 31 31 async put(tracks: Track[]) { 32 - return worker.call.putTracks(tracks); 32 + return worker.putTracks(tracks); 33 33 }, 34 34 }, 35 35 });
+2 -2
src/pages/output/native-fs/_applet.astro
··· 34 34 35 35 tracks: { 36 36 async get() { 37 - return worker.call.getTracks(); 37 + return worker.getTracks(); 38 38 }, 39 39 40 40 async put(tracks: Track[]) { 41 - return worker.call.putTracks(tracks); 41 + return worker.putTracks(tracks); 42 42 }, 43 43 }, 44 44 });
+2 -2
src/pages/processor/artwork/_applet.astro
··· 20 20 // ACTIONS 21 21 //////////////////////////////////////////// 22 22 function artwork(request: ArtworkRequest) { 23 - return worker.call.artwork(request); 23 + return worker.artwork(request); 24 24 } 25 25 26 26 function supply(items: ArtworkRequest[]) { 27 - return worker.call.supply(items); 27 + return worker.supply(items); 28 28 } 29 29 30 30 context.setActionHandler("artwork", artwork);
+1 -1
src/pages/processor/metadata/_applet.astro
··· 19 19 // ACTIONS 20 20 //////////////////////////////////////////// 21 21 const supply: Actions["supply"] = (...args: Parameters<Actions["supply"]>) => { 22 - return worker.call.supply(...args); 22 + return worker.supply(...args); 23 23 }; 24 24 25 25 context.setActionHandler("supply", supply);
+2 -2
src/pages/processor/search/_applet.astro
··· 23 23 context.setActionHandler("supply", supply); 24 24 25 25 async function search(term: string): Promise<Track[]> { 26 - return worker.call.search(term); 26 + return worker.search(term); 27 27 } 28 28 29 29 async function supply(tracks: Track[]) { 30 - return worker.call.supply(tracks); 30 + return worker.supply(tracks); 31 31 } 32 32 </script>
+11 -5
src/scripts/common.ts
··· 1 1 import * as Uint8 from "uint8arrays"; 2 - import { createEndpoint, type MessageEndpoint } from "@remote-ui/rpc"; 2 + import * as Comlink from "comlink"; 3 3 import { xxh32 } from "xxh32"; 4 + import { getTransferables } from "@okikio/transferables"; 4 5 5 6 import type { Track } from "@applets/core/types"; 6 7 ··· 46 47 return xxh32(JSON.stringify(value)); 47 48 } 48 49 49 - export function endpoint<T extends Record<string, any>>(ini: MessageEndpoint) { 50 - const e = createEndpoint<T>(ini); 50 + export function endpoint<T extends Record<string, any>>(ini: Comlink.Endpoint) { 51 + const e = Comlink.wrap<T>(ini); 51 52 if ("start" in ini && typeof ini.start === "function") ini.start(); 52 53 return e; 53 54 } ··· 56 57 if (globalThis.SharedWorkerGlobalScope && self instanceof SharedWorkerGlobalScope) { 57 58 self.onconnect = (event: MessageEvent) => { 58 59 const port = event.ports[0]; 59 - createEndpoint<T>(port).expose(actions); 60 + Comlink.expose(actions, port); 60 61 port.start(); 61 62 }; 62 63 63 64 (self as any).connected = true; 64 65 } else { 65 - createEndpoint<T>(self).expose(actions); 66 + Comlink.expose(actions, self); 66 67 } 67 68 68 69 return actions; ··· 99 100 .digest("SHA-256", new TextEncoder().encode(track.uri)) 100 101 .then((a) => Uint8.toString(new Uint8Array(a), "base64url")); 101 102 } 103 + 104 + export function transfer<T = unknown>(a: T) { 105 + const b = getTransferables(a); 106 + return Comlink.transfer(a, b); 107 + }