fullstacked 0.11.3-1148 → 0.12.0-1169

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.
@@ -1,153 +0,0 @@
1
- const te = new TextEncoder();
2
- const td = new TextDecoder();
3
-
4
- export enum DataType {
5
- UNDEFINED = 0,
6
- BOOLEAN = 1,
7
- STRING = 2,
8
- NUMBER = 3,
9
- BUFFER = 4,
10
- ERROR = 5
11
- }
12
-
13
- function serializeNumber(n) {
14
- const view = new DataView(new ArrayBuffer(8));
15
- view.setFloat64(0, n);
16
- return new Uint8Array(view.buffer);
17
- }
18
-
19
- function deserializeNumber(bytes: Uint8Array) {
20
- const buffer = new ArrayBuffer(8);
21
- new Uint8Array(buffer).set(bytes);
22
- return new DataView(buffer).getFloat64(0);
23
- }
24
-
25
- export function numberTo4Bytes(n: number) {
26
- const uint8Array = new Uint8Array(4);
27
- uint8Array[0] = (n & 0xff000000) >> 24;
28
- uint8Array[1] = (n & 0x00ff0000) >> 16;
29
- uint8Array[2] = (n & 0x0000ff00) >> 8;
30
- uint8Array[3] = (n & 0x000000ff) >> 0;
31
- return uint8Array;
32
- }
33
-
34
- export function bytesToNumber(bytes: Uint8Array) {
35
- return (
36
- ((bytes[0] << 24) |
37
- (bytes[1] << 16) |
38
- (bytes[2] << 8) |
39
- (bytes[3] << 0)) >>>
40
- 0
41
- );
42
- }
43
-
44
- /*
45
-
46
- 1 byte for type
47
- 4 bytes for length
48
- n bytes for data
49
-
50
- */
51
-
52
- export function serializeArgs(args: any[]) {
53
- const parts = args.map((arg) => {
54
- let data: Uint8Array, type: DataType;
55
- if (typeof arg === "undefined" || arg === null) {
56
- type = DataType.UNDEFINED;
57
- data = new Uint8Array(0);
58
- } else if (ArrayBuffer.isView(arg)) {
59
- type = DataType.BUFFER;
60
- data = new Uint8Array(arg.buffer);
61
- } else if (typeof arg === "boolean") {
62
- type = DataType.BOOLEAN;
63
- data = new Uint8Array([arg ? 1 : 0]);
64
- } else if (typeof arg === "string") {
65
- type = DataType.STRING;
66
- data = te.encode(arg);
67
- } else if (typeof arg === "number") {
68
- type = DataType.NUMBER;
69
- data = serializeNumber(arg);
70
- } else {
71
- console.error("Using unknown type with IPC call");
72
- return null;
73
- }
74
-
75
- return new Uint8Array([
76
- type,
77
- ...numberTo4Bytes(data.byteLength),
78
- ...data
79
- ]);
80
- });
81
-
82
- const totalLength = parts.reduce(
83
- (total, part) => total + part.byteLength,
84
- 0
85
- );
86
- const data = new Uint8Array(totalLength);
87
- parts.forEach((part, i) => {
88
- const offset = parts
89
- .slice(0, i)
90
- .reduce((total, b) => total + b.byteLength, 0);
91
- data.set(part, offset);
92
- });
93
-
94
- return data;
95
- }
96
-
97
- export function deserializeArgs(data: Uint8Array) {
98
- const args = [];
99
-
100
- let cursor = 0;
101
- while (cursor < data.byteLength) {
102
- const type = data[cursor] as DataType;
103
- cursor += 1;
104
- const length = bytesToNumber(data.slice(cursor, cursor + 4));
105
- cursor += 4;
106
- const arg = data.slice(cursor, cursor + length);
107
- cursor += length;
108
-
109
- switch (type) {
110
- case DataType.UNDEFINED:
111
- args.push(undefined);
112
- break;
113
- case DataType.BOOLEAN:
114
- args.push(arg.at(0) ? true : false);
115
- break;
116
- case DataType.STRING:
117
- args.push(td.decode(arg));
118
- break;
119
- case DataType.NUMBER:
120
- args.push(deserializeNumber(arg));
121
- break;
122
- case DataType.BUFFER:
123
- args.push(arg);
124
- break;
125
- case DataType.ERROR:
126
- throw td.decode(arg);
127
- }
128
- }
129
-
130
- return args;
131
- }
132
-
133
- export function convertObjectToArray(obj: object) {
134
- return Object.entries(obj).flat();
135
- }
136
-
137
- export function convertArrayToObject(arr: any[]) {
138
- let obj = {};
139
- for (let i = 0; i < arr.length; i += 2) {
140
- obj[arr[i]] = arr[i + 1];
141
- }
142
- return obj;
143
- }
144
-
145
- export function getLowestKeyIdAvailable(map: Map<number, any>) {
146
- const currentIds = Array.from(map.keys()).sort((a, b) => a - b);
147
- let requestId = 0;
148
- for (const id of currentIds) {
149
- if (requestId !== id) break;
150
- requestId++;
151
- }
152
- return requestId;
153
- }
@@ -1 +0,0 @@
1
- .snack-bars-container{display:flex;flex-direction:column;gap:10px;position:fixed;bottom:0;left:0;z-index:100;padding:0 20px 20px;align-items:flex-start;width:100%;pointer-events:none;text-align:left;font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif;font-size:16px;max-width:450px}@media(max-width: 450px){.snack-bars-container{align-items:center}}.snack-bars-container .snack-bar{pointer-events:all;background-color:#404958;border-radius:5px;color:#fff;min-height:42px;max-width:100%;width:max-content;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:5px 10px;box-shadow:0px 4px 10px rgba(21,23,27,.6)}.snack-bars-container .snack-bar>div:first-child{padding:5px 0;width:100%;overflow-wrap:break-word}
@@ -1,60 +0,0 @@
1
- /*
2
- This file must follow the figma design
3
- https://www.figma.com/design/xb3JBRCvEWpbwGda03T5QQ/Mockups?node-id=415-3655
4
- */
5
-
6
- import type { Button } from "@fullstacked/ui";
7
-
8
- type SnackBarOpt = {
9
- message: string;
10
- autoDismissTimeout?: number;
11
- button?: ReturnType<typeof Button>;
12
- };
13
-
14
- let snackBarsContainer: HTMLDivElement;
15
-
16
- export function SnackBar(opts: SnackBarOpt) {
17
- if (!snackBarsContainer) {
18
- snackBarsContainer = document.createElement("div");
19
- snackBarsContainer.classList.add("snack-bars-container");
20
- document.body.append(snackBarsContainer);
21
- }
22
-
23
- const container = document.createElement("div");
24
- container.classList.add("snack-bar");
25
-
26
- const text = document.createElement("div");
27
- text.innerHTML = opts.message;
28
- container.append(text);
29
-
30
- if (opts.button) {
31
- container.append(opts.button);
32
- }
33
-
34
- container.style.transform = "translateY(100%)";
35
- container.style.transition = "300ms transform";
36
- snackBarsContainer.append(container);
37
- setTimeout(() => (container.style.transform = "translateY(0%)"));
38
-
39
- let timeout: ReturnType<typeof setTimeout>;
40
- const dismiss = () => {
41
- clearTimeout(timeout);
42
-
43
- const animDuration = 500;
44
- container.style.transition = `${animDuration}ms opacity`;
45
- container.style.opacity = "0";
46
- setTimeout(() => {
47
- container.remove();
48
- if (snackBarsContainer?.children.length === 0) {
49
- snackBarsContainer.remove();
50
- snackBarsContainer = null;
51
- }
52
- }, animDuration);
53
- };
54
-
55
- if (opts.autoDismissTimeout) {
56
- setTimeout(dismiss, opts.autoDismissTimeout);
57
- }
58
-
59
- return { dismiss };
60
- }
@@ -1,125 +0,0 @@
1
- import { bridge } from "../bridge";
2
- import {
3
- deserializeArgs,
4
- numberTo4Bytes,
5
- serializeArgs
6
- } from "../bridge/serialization";
7
- import core_message from "../core_message";
8
- import { toByteArray } from "../base64";
9
-
10
- export type Data = string | number | boolean | Uint8Array;
11
-
12
- type DataChannelCallback = (data: Data[]) => void;
13
-
14
- type DataChannel = {
15
- send(...args: Data[]): void;
16
- on(callback: DataChannelCallback): void;
17
- off(callback: DataChannelCallback): void;
18
- };
19
-
20
- type DataChannelRawCallback = (data: Uint8Array) => void;
21
-
22
- type DataChannelRaw = {
23
- send(buffer: Uint8Array): void;
24
- on(callback: DataChannelRawCallback): void;
25
- off(callback: DataChannelRawCallback): void;
26
- };
27
-
28
- type Channel = {
29
- raw: false;
30
- listeners: Set<DataChannelCallback>;
31
- };
32
-
33
- type ChannelRaw = {
34
- raw: true;
35
- listeners: Set<DataChannelRawCallback>;
36
- };
37
-
38
- const channels = new Map<string, Channel | ChannelRaw>();
39
-
40
- // 20
41
- export function connect(
42
- name: string,
43
- port: number,
44
- host?: string,
45
- raw?: false
46
- ): Promise<DataChannel>;
47
- export function connect(
48
- name: string,
49
- port: number,
50
- host: string,
51
- raw: true
52
- ): Promise<DataChannelRaw>;
53
- export function connect(
54
- name: string,
55
- port: number,
56
- host = "localhost",
57
- raw = false
58
- ) {
59
- const payload = new Uint8Array([
60
- 20,
61
- ...serializeArgs([name, port, host, raw])
62
- ]);
63
-
64
- const transformer = ([channelId]) => {
65
- if (raw) {
66
- const listeners = new Set<DataChannelRawCallback>();
67
-
68
- const channel: ChannelRaw = {
69
- raw: true,
70
- listeners
71
- };
72
-
73
- channels.set(channelId, channel);
74
-
75
- core_message.addListener("channel-" + channelId, (dataStr) => {
76
- const data = toByteArray(dataStr);
77
- listeners.forEach((cb) => cb(data));
78
- });
79
-
80
- return {
81
- send: (data) => send(channelId, data),
82
- on: (cb) => listeners.add(cb),
83
- off: (cb) => listeners.add(cb)
84
- } as DataChannelRaw;
85
- } else {
86
- const listeners = new Set<DataChannelCallback>();
87
-
88
- const channel: Channel = {
89
- raw: false,
90
- listeners
91
- };
92
-
93
- core_message.addListener("channel-" + channelId, (dataStr) => {
94
- const data = toByteArray(dataStr);
95
- listeners.forEach((cb) => cb(deserializeArgs(data)));
96
- });
97
-
98
- channels.set(channelId, channel);
99
-
100
- return {
101
- send: (...data) => {
102
- const body = serializeArgs(data);
103
- send(
104
- channelId,
105
- new Uint8Array([
106
- ...numberTo4Bytes(body.byteLength),
107
- ...body
108
- ])
109
- );
110
- },
111
- on: (cb) => listeners.add(cb),
112
- off: (cb) => listeners.add(cb)
113
- } as DataChannel;
114
- }
115
- };
116
-
117
- return bridge(payload, transformer);
118
- }
119
-
120
- // 21
121
- function send(channelId: string, data: Uint8Array) {
122
- const payload = new Uint8Array([21, ...serializeArgs([channelId, data])]);
123
-
124
- return bridge(payload);
125
- }
@@ -1,76 +0,0 @@
1
- import { bridge } from "../bridge";
2
- import { serializeArgs } from "../bridge/serialization";
3
- import { SnackBar } from "../components/snackbar";
4
-
5
- const coreMessageListeners = new Map<string, Set<(message: string) => void>>();
6
- export const addListener = (
7
- messageType: string,
8
- cb: (message: string) => void
9
- ) => {
10
- let listeners = coreMessageListeners.get(messageType);
11
- if (!listeners) {
12
- listeners = new Set<typeof cb>();
13
- coreMessageListeners.set(messageType, listeners);
14
- }
15
- listeners.add(cb);
16
-
17
- const pending = pendingMessages.get(messageType);
18
- if (pending?.length) {
19
- for (const m of pending) {
20
- cb(m);
21
- }
22
- }
23
- };
24
- export const removeListener = (
25
- messageType: string,
26
- cb: (message: string) => void
27
- ) => {
28
- let listeners = coreMessageListeners.get(messageType);
29
- listeners?.delete(cb);
30
- if (listeners?.size === 0) {
31
- coreMessageListeners.delete(messageType);
32
- }
33
- };
34
-
35
- const pendingMessages = new Map<string, string[]>();
36
- setInterval(() => pendingMessages.clear(), 10 * 1000); // 10s
37
-
38
- globalThis.oncoremessage = (messageType: string, message: string) => {
39
- const listeners = coreMessageListeners.get(messageType);
40
- if (!listeners?.size) {
41
- let pending = pendingMessages.get(messageType);
42
- if (!pending) {
43
- pending = [];
44
- pendingMessages.set(messageType, pending);
45
- }
46
- pending.push(message);
47
- } else {
48
- listeners?.forEach((cb) => cb(message));
49
- }
50
- };
51
-
52
- addListener("hello", console.log);
53
- addListener("log", console.log);
54
- addListener("alert", (message) => {
55
- SnackBar({
56
- message,
57
- autoDismissTimeout: 4000
58
- });
59
- });
60
-
61
- // 40
62
- function setTitle(title: string) {
63
- const payload = new Uint8Array([
64
- 40,
65
- ...serializeArgs([title])
66
- ]);
67
- bridge(payload);
68
- }
69
-
70
- let lastTitleSeen = null;
71
- setInterval(() => {
72
- if(lastTitleSeen !== document.title) {
73
- setTitle(document.title);
74
- }
75
- lastTitleSeen = document.title;
76
- }, 500)
@@ -1,3 +0,0 @@
1
- import * as core_message from "./core_message";
2
- export default core_message;
3
- export * from "./core_message";