A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

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

feat: initial setup for workers

+156 -20
-17
_backup/scripts/common.ts
··· 22 22 // 🛠️ 23 23 //////////////////////////////////////////// 24 24 25 - export function arrayShuffle<T>(array: Array<T>): Array<T> { 26 - if (array.length === 0) { 27 - return []; 28 - } 29 - 30 - array = [...array]; 31 - 32 - for (let index = array.length - 1; index > 0; index--) { 33 - const randArr = crypto.getRandomValues(new Uint32Array(1)); 34 - const randVal = randArr[0] / 2 ** 32; 35 - const newIndex = Math.floor(randVal * (index + 1)); 36 - [array[index], array[newIndex]] = [array[newIndex], array[index]]; 37 - } 38 - 39 - return array; 40 - } 41 - 42 25 export function cleanUndefinedValuesForTracks(tracks: Track[]): Track[] { 43 26 return tracks.map((track) => { 44 27 const t = { ...track };
+4 -1
deno.jsonc
··· 1 1 { 2 2 "imports": { 3 - // Dependencies 3 + "@mys/m-rpc": "jsr:@mys/m-rpc@^0.12.2", 4 + "@mys/worker-fn": "jsr:@mys/worker-fn@^3.2.1", 5 + "@okikio/transferables": "jsr:@okikio/transferables@^1.0.2", 4 6 "@std/fs": "jsr:@std/fs@^1.0.15", 5 7 "alien-signals": "npm:alien-signals@^3.0.0", 6 8 "lume/": "https://deno.land/x/lume@v3.0.11/", ··· 10 12 // Source 11 13 "@common/": "./src/common/", 12 14 "@component/": "./src/component/", 15 + "xxh32": "npm:xxh32@^2.0.5", 13 16 }, 14 17 "tasks": { 15 18 "build": "deno task lume",
+28 -2
deno.lock
··· 2 2 "version": "5", 3 3 "specifiers": { 4 4 "jsr:@deno/loader@0.3.6": "0.3.6", 5 + "jsr:@mys/m-rpc@~0.12.2": "0.12.2", 6 + "jsr:@mys/worker-fn@^3.2.1": "3.2.1", 7 + "jsr:@okikio/transferables@^1.0.2": "1.0.2", 5 8 "jsr:@std/cli@1.0.22": "1.0.22", 6 9 "jsr:@std/cli@^1.0.21": "1.0.22", 7 10 "jsr:@std/collections@^1.1.3": "1.1.3", ··· 42 45 "npm:morphdom@^2.7.7": "2.7.7", 43 46 "npm:postcss-import@16.1.1": "16.1.1_postcss@8.5.6", 44 47 "npm:postcss@8.5.6": "8.5.6", 45 - "npm:sass@1.93.2": "1.93.2" 48 + "npm:sass@1.93.2": "1.93.2", 49 + "npm:xxh32@^2.0.5": "2.0.5" 46 50 }, 47 51 "jsr": { 48 52 "@deno/loader@0.3.6": { 49 53 "integrity": "98f08d837c18ece5ba15122264fb29580967407c34e6552e152b8f453a60c2be" 54 + }, 55 + "@mys/m-rpc@0.12.2": { 56 + "integrity": "36599d3d4708db9f5c0f7da35a17b7e7da1fafddb69de6cfcdc6afe94cd4f084", 57 + "dependencies": [ 58 + "jsr:@okikio/transferables" 59 + ] 60 + }, 61 + "@mys/worker-fn@3.2.1": { 62 + "integrity": "330960f21041edd20fa9c5f78b136f62e3781e35797ac635534f003545be76cd", 63 + "dependencies": [ 64 + "jsr:@mys/m-rpc" 65 + ] 66 + }, 67 + "@okikio/transferables@1.0.2": { 68 + "integrity": "46a80015a1c4672b0b246e38838b3ea1e2edc6c775a235184a2f8eb49a8314f7" 50 69 }, 51 70 "@std/cli@1.0.22": { 52 71 "integrity": "50d1e4f87887cb8a8afa29b88505ab5081188f5cad3985460c3b471fa49ff21a" ··· 488 507 "picocolors" 489 508 ], 490 509 "bin": true 510 + }, 511 + "xxh32@2.0.5": { 512 + "integrity": "sha512-glQIaPvLHV4xG2Sn0E4mZWY25JT34+XcG4e2c8OMIH2SXxVrm6MmJ8miCsqGBLtf+rn2YcaeS11vq/66vkXGUQ==" 491 513 } 492 514 }, 493 515 "remote": { ··· 748 770 }, 749 771 "workspace": { 750 772 "dependencies": [ 773 + "jsr:@mys/m-rpc@~0.12.2", 774 + "jsr:@mys/worker-fn@^3.2.1", 775 + "jsr:@okikio/transferables@^1.0.2", 751 776 "jsr:@std/fs@^1.0.15", 752 777 "npm:alien-signals@3", 753 - "npm:morphdom@^2.7.7" 778 + "npm:morphdom@^2.7.7", 779 + "npm:xxh32@^2.0.5" 754 780 ] 755 781 } 756 782 }
+21
src/common/index.js
··· 1 + /** 2 + * @template T 3 + * @param {Array<T>} array 4 + * @returns Array<T> 5 + */ 6 + export function arrayShuffle(array) { 7 + if (array.length === 0) { 8 + return []; 9 + } 10 + 11 + array = [...array]; 12 + 13 + for (let index = array.length - 1; index > 0; index--) { 14 + const randArr = crypto.getRandomValues(new Uint32Array(1)); 15 + const randVal = randArr[0] / 2 ** 32; 16 + const newIndex = Math.floor(randVal * (index + 1)); 17 + [array[index], array[newIndex]] = [array[newIndex], array[index]]; 18 + } 19 + 20 + return array; 21 + }
+2
src/common/worker.d.ts
··· 1 + export type Announcement<T> = MRpcBaseMsg & { type: "announcement"; args: T }; 2 + export type MRpcBaseMsg = { ns: string; name: string; key: number };
+59
src/common/worker.js
··· 1 + import { defineWorkerFn, useWorkerFn } from "@mys/worker-fn"; 2 + import { getTransferables } from "@okikio/transferables"; 3 + import { xxh32 } from "xxh32"; 4 + 5 + /** 6 + * @import {Announcement} from "./worker.d.ts" 7 + */ 8 + 9 + export const define = defineWorkerFn; 10 + export const use = useWorkerFn; 11 + 12 + /** 13 + * @template T 14 + * @param {string} name 15 + * @param {T} args 16 + */ 17 + export function announce(name, args) { 18 + const transferables = getTransferables(args); 19 + globalThis.postMessage(constructMsg(name, args), { transfer: transferables }); 20 + } 21 + 22 + /** 23 + * @template T 24 + * @param {string} name 25 + * @param {(args: T) => void} fn 26 + */ 27 + export function listen(name, fn) { 28 + globalThis.addEventListener("message", (event) => { 29 + const announcement = 30 + /** @type {Announcement<T>} */ (/** @type {unknown} */ (event)); 31 + const { ns, type } = announcement; 32 + 33 + if (announcement.name !== name) return; 34 + if (ns !== ANNOUNCEMENT || type !== ANNOUNCEMENT) return; 35 + 36 + fn(announcement.args); 37 + }); 38 + } 39 + 40 + // PRIVATE 41 + 42 + const ANNOUNCEMENT = "announcement"; 43 + 44 + /** 45 + * @template T 46 + * @param {string} name 47 + * @param {T} args 48 + * @returns {Announcement<T>} 49 + */ 50 + function constructMsg(name, args) { 51 + return { 52 + ns: ANNOUNCEMENT, 53 + name, 54 + key: xxh32(crypto.randomUUID()), 55 + 56 + type: ANNOUNCEMENT, 57 + args, 58 + }; 59 + }
+42
src/component/engine/queue/worker.js
··· 1 + import { announce, define } from "@common/worker.js"; 2 + import { effect, signal } from "@common/signal.js"; 3 + 4 + /** 5 + * @import {Track} from "@component/core/types.d.ts" 6 + */ 7 + 8 + //////////////////////////////////////////// 9 + // STATE 10 + //////////////////////////////////////////// 11 + 12 + const pools = signal(/** @type {Record<string, { pool: Track[] }>} */ ({})); 13 + 14 + //////////////////////////////////////////// 15 + // ACTIONS 16 + //////////////////////////////////////////// 17 + 18 + define("pool", pool); 19 + 20 + /** 21 + * @param {{ groupId: string; tracks: Track[] }} _ 22 + */ 23 + function pool({ groupId, tracks }) { 24 + fill(); 25 + 26 + // TODO: 27 + // Create a signal for each group: future, past, now 28 + // Whenever that state changes it should create an annoucement. 29 + // Custom elements on the main thread can then listen for those. 30 + } 31 + 32 + // PRIVATE 33 + 34 + function fill() { 35 + } 36 + 37 + function todo() { 38 + effect(() => { 39 + const data = groupSignal(); 40 + announce("some-name", data); 41 + }); 42 + }