@apple-pie/slice 0.1.3 → 0.1.4

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.
Files changed (68) hide show
  1. package/README.md +47 -77
  2. package/dist/cjs/chunks/{Button-hg5kGC1P.js → Button-krf4dQeL.js} +4 -2
  3. package/dist/cjs/chunks/{FileList-BQgcnKPP.js → FileList-CkpMj-os.js} +1 -1
  4. package/dist/cjs/chunks/{ProgressIndicator-qjya_Yb5.js → ProgressIndicator-DVD-gD3T.js} +1 -1
  5. package/dist/cjs/chunks/{PromptInput-ZqHQUfXw.js → PromptInput-DULf5ock.js} +1 -1
  6. package/dist/cjs/chunks/SSEConnection-B_yE8cXz.js +140 -0
  7. package/dist/cjs/chunks/{TextArea-BhzVGfKA.js → TextArea-BJCjRUEG.js} +1 -1
  8. package/dist/cjs/chunks/{TextField-hIjxrOG9.js → TextField-CjT26H_6.js} +18 -16
  9. package/dist/cjs/chunks/{UploadArea-B4GA06LW.js → UploadArea-BE6but3t.js} +1 -1
  10. package/dist/cjs/chunks/WSConnection-DCBuJGmb.js +206 -0
  11. package/dist/cjs/chunks/{sseStore-Dg0WuXsI.js → sseStore-CIIeshjm.js} +3 -3
  12. package/dist/cjs/chunks/windowStore-CCxCOUqa.js +156 -0
  13. package/dist/cjs/components/Button/index.js +2 -2
  14. package/dist/cjs/components/FileList/index.js +2 -2
  15. package/dist/cjs/components/Progress/index.js +2 -2
  16. package/dist/cjs/components/PromptInput/index.js +4 -4
  17. package/dist/cjs/components/TextArea/index.js +3 -3
  18. package/dist/cjs/components/Textfield/index.js +3 -3
  19. package/dist/cjs/components/UploadArea/index.js +7 -8
  20. package/dist/cjs/hooks/useWindow.js +46 -11
  21. package/dist/cjs/index.js +2 -2
  22. package/dist/cjs/stores/SSE.js +2 -2
  23. package/dist/cjs/stores/WS.js +62 -0
  24. package/dist/cjs/stores/window.js +14 -3
  25. package/dist/cjs/stores.js +15 -4
  26. package/dist/cjs/utils/index.js +2 -2
  27. package/dist/cjs/utils/objects/index.js +4 -138
  28. package/dist/esm/chunks/{Button-DJDS7Yad.mjs → Button-kXFJmcKv.mjs} +4 -2
  29. package/dist/esm/chunks/{FileList-CmlXqPXl.mjs → FileList-Bon537-t.mjs} +1 -1
  30. package/dist/esm/chunks/{PromptInput-DSHVUuEf.mjs → PromptInput-DXFAZspz.mjs} +3 -3
  31. package/dist/esm/chunks/SSEConnection-Dj9P0SWE.mjs +140 -0
  32. package/dist/esm/chunks/{TextArea-CyVBzMoN.mjs → TextArea-DBmM6aQm.mjs} +1 -1
  33. package/dist/esm/chunks/{TextField-CYI2vbvO.mjs → TextField-DyUTMegV.mjs} +18 -16
  34. package/dist/esm/chunks/{UploadArea-Kez3VD4d.mjs → UploadArea-tT5V8q23.mjs} +3 -3
  35. package/dist/esm/chunks/WSConnection-DlYSitff.mjs +206 -0
  36. package/dist/esm/chunks/{sseStore-m3IPyLwJ.mjs → sseStore-DdqmnAAf.mjs} +2 -2
  37. package/dist/esm/chunks/windowStore-BOTh1g37.mjs +148 -0
  38. package/dist/esm/components/Button/index.mjs +2 -2
  39. package/dist/esm/components/FileList/index.mjs +2 -2
  40. package/dist/esm/components/Progress/index.mjs +3 -3
  41. package/dist/esm/components/PromptInput/index.mjs +4 -4
  42. package/dist/esm/components/TextArea/index.mjs +3 -3
  43. package/dist/esm/components/Textfield/index.mjs +3 -3
  44. package/dist/esm/components/UploadArea/index.mjs +7 -7
  45. package/dist/esm/hooks/useWindow.mjs +47 -11
  46. package/dist/esm/index.mjs +7 -7
  47. package/dist/esm/stores/SSE.mjs +2 -2
  48. package/dist/esm/stores/WS.mjs +59 -0
  49. package/dist/esm/stores/window.mjs +3 -1
  50. package/dist/esm/stores.mjs +5 -5
  51. package/dist/esm/utils/index.mjs +3 -1
  52. package/dist/esm/utils/objects/index.mjs +4 -139
  53. package/dist/types/hooks/index.d.ts +1 -1
  54. package/dist/types/hooks/useWindow/useWindow.d.ts +19 -0
  55. package/dist/types/index.d.ts +1 -1
  56. package/dist/types/stores/WS/_types.d.ts +17 -0
  57. package/dist/types/stores/WS/index.d.ts +2 -0
  58. package/dist/types/stores/WS/wsStore.d.ts +19 -0
  59. package/dist/types/stores/window/_types.d.ts +5 -0
  60. package/dist/types/stores/window/index.d.ts +3 -2
  61. package/dist/types/stores/window/windowStore.d.ts +8 -0
  62. package/dist/types/utils/index.d.ts +2 -2
  63. package/dist/types/utils/objects/WSConnection/WSConnection.d.ts +147 -0
  64. package/dist/types/utils/objects/index.d.ts +2 -0
  65. package/package.json +1 -1
  66. package/dist/cjs/chunks/windowStore-RaJswiHM.js +0 -70
  67. package/dist/esm/chunks/windowStore-CwW0i_le.mjs +0 -71
  68. package/dist/esm/chunks/{ProgressIndicator-h11R3FG1.mjs → ProgressIndicator-D2eairZl.mjs} +2 -2
@@ -1,7 +1,7 @@
1
- export { u as useConnectionClose, a as useConnectionMessage, b as useIsConnected, c as useLastSSEMessage, d as useMessage, e as useSSE, f as useSSEActions, g as useSSEStore } from "../chunks/sseStore-m3IPyLwJ.mjs";
1
+ export { u as useConnectionClose, a as useConnectionMessage, b as useIsConnected, c as useLastSSEMessage, d as useMessage, e as useSSE, f as useSSEActions, g as useSSEStore } from "../chunks/sseStore-DdqmnAAf.mjs";
2
2
 
3
3
  import "zustand";
4
4
 
5
5
  import "../chunks/tslib.es6-c-7TIv71.mjs";
6
6
 
7
- import "../utils/objects/index.mjs";
7
+ import "../chunks/SSEConnection-Dj9P0SWE.mjs";
@@ -0,0 +1,59 @@
1
+ import { create } from "zustand";
2
+
3
+ import "../chunks/tslib.es6-c-7TIv71.mjs";
4
+
5
+ import { W as WSConnection } from "../chunks/WSConnection-DlYSitff.mjs";
6
+
7
+ const useWSStore = create((set, get) => ({
8
+ connections: [],
9
+ message: null,
10
+ closedConnection: null,
11
+ actions: {
12
+ addConnection: (name, options) => {
13
+ const existingConnection = get().connections.find(c => c.name === name);
14
+ null == existingConnection || existingConnection.connection.close({
15
+ code: 1e3,
16
+ reason: "Connection replaced"
17
+ });
18
+ const userOnMessageCallback = options.onMessageCallback, connection = new WSConnection(Object.assign(Object.assign({}, options), {
19
+ unifiedMessages: !0,
20
+ onMessageCallback: message => {
21
+ set({
22
+ message: message
23
+ }), null == userOnMessageCallback || userOnMessageCallback(message), "close" === message.type && set({
24
+ closedConnection: name
25
+ });
26
+ }
27
+ })), nextConnection = {
28
+ name: name,
29
+ connection: connection
30
+ };
31
+ return set(state => ({
32
+ connections: [ ...state.connections.filter(connection => connection.name !== name), nextConnection ]
33
+ })), nextConnection;
34
+ },
35
+ removeConnection: name => {
36
+ const existingConnection = get().connections.find(c => c.name === name);
37
+ existingConnection && (existingConnection.connection.close({
38
+ code: 1e3,
39
+ reason: "Connection removed"
40
+ }), set(state => ({
41
+ connections: state.connections.filter(connection => connection.name !== name)
42
+ })));
43
+ }
44
+ }
45
+ })), useWS = () => useWSStore(state => state.actions), useConnectionClose = () => useWSStore(state => state.closedConnection), useConnectionMessage = connection => useWSStore(state => state.connections.some(entry => entry.name === connection) ? state.message : null), useIsConnected = connection => useWSStore(state => {
46
+ var _a, _b;
47
+ return connection ? null !== (_b = null === (_a = state.connections.find(entry => entry.name === connection)) || void 0 === _a ? void 0 : _a.connection.connected) && void 0 !== _b && _b : state.connections.some(entry => entry.connection.connected);
48
+ });
49
+
50
+ function useMessage(type, connection) {
51
+ return useWSStore(state => {
52
+ const sourceMessage = connection && !state.connections.some(c => c.name === connection) ? null : state.message;
53
+ return type ? (null == sourceMessage ? void 0 : sourceMessage.type) !== type ? null : "open" === type || "error" === type || "close" === type ? "event" in sourceMessage ? sourceMessage.event : null : "data" in sourceMessage ? sourceMessage.data : null : sourceMessage;
54
+ });
55
+ }
56
+
57
+ const useWSActions = useWSStore.getState().actions, useLastWSMessage = () => useWSStore.getState().message;
58
+
59
+ export { useConnectionClose, useConnectionMessage, useIsConnected, useLastWSMessage, useMessage, useWS, useWSActions, useWSStore };
@@ -1,3 +1,5 @@
1
- export { F as FormFactor, u as useWindowStore } from "../chunks/windowStore-CwW0i_le.mjs";
1
+ export { F as FormFactor, d as dpr, f as formFactor, g as gettingLocation, i as isAppleDevice, a as isElectron, b as isTouchDevice, l as location, c as locationError, u as useDpr, e as useFormFactor, h as useGetLocation, j as useGettingLocation, k as useInitializeWindow, m as useIsAppleDevice, n as useIsElectron, o as useIsTouchDevice, p as useLocation, q as useLocationError, r as useViewportHeight, s as useViewportWidth, t as useWindowStore, v as viewportHeight, w as viewportWidth } from "../chunks/windowStore-BOTh1g37.mjs";
2
+
3
+ import "../chunks/tslib.es6-c-7TIv71.mjs";
2
4
 
3
5
  import "zustand";
@@ -1,4 +1,4 @@
1
- export { F as FormFactor, u as useWindowStore } from "./chunks/windowStore-CwW0i_le.mjs";
1
+ export { F as FormFactor, d as dpr, f as formFactor, g as gettingLocation, i as isAppleDevice, a as isElectron, b as isTouchDevice, l as location, c as locationError, u as useDpr, e as useFormFactor, h as useGetLocation, j as useGettingLocation, k as useInitializeWindow, m as useIsAppleDevice, n as useIsElectron, o as useIsTouchDevice, p as useLocation, q as useLocationError, r as useViewportHeight, s as useViewportWidth, t as useWindowStore, v as viewportHeight, w as viewportWidth } from "./chunks/windowStore-BOTh1g37.mjs";
2
2
 
3
3
  export { c as createUploadsWorker, g as getUploads, a as getUploadsError, b as getUploadsWorkerStatus, u as uploadsActions, d as uploadsInitialized, e as useUploads, f as useUploadsActions, h as useUploadsError, i as useUploadsInitialized, j as useUploadsStore, k as useUploadsWorkerStatus } from "./chunks/uploadsStore-D69fEXMY.mjs";
4
4
 
@@ -6,12 +6,12 @@ export { g as getTip, t as tipActions, u as useTip, a as useTipActions, b as use
6
6
 
7
7
  export { g as getToast, t as toastActions, u as useToast, a as useToastActions, b as useToastStore } from "./chunks/toastStore-D2PEIqCo.mjs";
8
8
 
9
- export { u as useConnectionClose, a as useConnectionMessage, b as useIsConnected, c as useLastSSEMessage, d as useMessage, e as useSSE, f as useSSEActions, g as useSSEStore } from "./chunks/sseStore-m3IPyLwJ.mjs";
9
+ export { u as useConnectionClose, a as useConnectionMessage, b as useIsConnected, c as useLastSSEMessage, d as useMessage, e as useSSE, f as useSSEActions, g as useSSEStore } from "./chunks/sseStore-DdqmnAAf.mjs";
10
+
11
+ import "./chunks/tslib.es6-c-7TIv71.mjs";
10
12
 
11
13
  import "zustand";
12
14
 
13
15
  import "./chunks/uploads-worker-Dv-4zGnC.mjs";
14
16
 
15
- import "./chunks/tslib.es6-c-7TIv71.mjs";
16
-
17
- import "./utils/objects/index.mjs";
17
+ import "./chunks/SSEConnection-Dj9P0SWE.mjs";
@@ -2,6 +2,8 @@ export { c as copyToClipboard } from "../chunks/misc-cg9I7drO.mjs";
2
2
 
3
3
  export { a as addOpacity, t as tintFromColor } from "../chunks/colors-DR9fLI5X.mjs";
4
4
 
5
- export { SSEConnection } from "./objects/index.mjs";
5
+ export { S as SSEConnection } from "../chunks/SSEConnection-Dj9P0SWE.mjs";
6
+
7
+ export { W as WSConnection } from "../chunks/WSConnection-DlYSitff.mjs";
6
8
 
7
9
  import "../chunks/tslib.es6-c-7TIv71.mjs";
@@ -1,140 +1,5 @@
1
- class SSEConnection {
2
- /**
3
- * Whether the underlying EventSource is currently open.
4
- */
5
- get connected() {
6
- var _a;
7
- return (null === (_a = this.sseConnection) || void 0 === _a ? void 0 : _a.readyState) === EventSource.OPEN;
8
- }
9
- /**
10
- * Direct access to the underlying EventSource instance.
11
- */ get connection() {
12
- return this.sseConnection;
13
- }
14
- /**
15
- * Create an SEE connection instance
16
- */ constructor(options) {
17
- var _a, _b, _c;
18
- this.sseConnection = null, this.customEventHandlers = new Map, this.unifiedOnMessage = !1,
19
- /**
20
- * One message received
21
- */
22
- this.onMessage = event => {
23
- const data = this.parseEventData(event.data);
24
- this.emitUnifiedMessage({
25
- type: "message",
26
- data: data,
27
- event: event
28
- }), this.emitParsedMessage(data), this.shouldCloseFromMessage(event.data, data) && this.closeFromConnectionEvent();
29
- },
30
- /**
31
- * On error event
32
- */
33
- this.onError = event => {
34
- var _a;
35
- null === (_a = this.onErrorCallback) || void 0 === _a || _a.call(this, event), this.emitUnifiedMessage({
36
- type: "error",
37
- event: event
38
- });
39
- },
40
- /**
41
- * On open event
42
- */
43
- this.onOpen = event => {
44
- var _a;
45
- null === (_a = this.onOpenCallback) || void 0 === _a || _a.call(this, event), this.emitUnifiedMessage({
46
- type: "open",
47
- event: event
48
- });
49
- },
50
- /**
51
- * Close the SSE connection and release resources.
52
- */
53
- this.close = () => {
54
- this.sseConnection && (this.detachAllEventListeners(this.sseConnection), this.sseConnection.close(),
55
- this.sseConnection = null);
56
- }, this.url = null !== (_a = null == options ? void 0 : options.url) && void 0 !== _a ? _a : "",
57
- this.options = null !== (_b = null == options ? void 0 : options.options) && void 0 !== _b ? _b : void 0,
58
- this.unifiedOnMessage = null !== (_c = null == options ? void 0 : options.unifiedOnMessage) && void 0 !== _c && _c,
59
- this.onMessageCallback = null == options ? void 0 : options.onMessageCallback, this.onErrorCallback = null == options ? void 0 : options.onErrorCallback,
60
- this.onOpenCallback = null == options ? void 0 : options.onOpenCallback, this.onCloseCallback = null == options ? void 0 : options.onCloseCallback,
61
- this.connectionClose = null == options ? void 0 : options.connectionClose, (null == options ? void 0 : options.customEvents) ? this.customEvents = Array.isArray(null == options ? void 0 : options.customEvents) ? options.customEvents : [ options.customEvents ] : this.customEvents = [],
62
- this.sseConnection = new EventSource(this.url, this.options), this.attachDefaultEventListeners(this.sseConnection),
63
- this.customEvents.length > 0 && this.attachCustomEventListeners(this.customEvents);
64
- }
65
- /**
66
- * Safely parse SSE event data. Falls back to the raw string when the payload is not JSON.
67
- */ parseEventData(rawData) {
68
- try {
69
- return JSON.parse(rawData);
70
- } catch (_a) {
71
- return rawData;
72
- }
73
- }
74
- /**
75
- * Attach default SEE events
76
- */ attachDefaultEventListeners(connection) {
77
- connection.addEventListener("message", this.onMessage), connection.addEventListener("error", this.onError),
78
- connection.addEventListener("open", this.onOpen);
79
- }
80
- emitParsedMessage(data) {
81
- var _a;
82
- this.unifiedOnMessage || null === (_a = this.onMessageCallback) || void 0 === _a || _a.call(this, data);
83
- }
84
- emitUnifiedMessage(message) {
85
- var _a;
86
- this.unifiedOnMessage && (null === (_a = this.onMessageCallback) || void 0 === _a || _a.call(this, message));
87
- }
88
- emitCloseEvent(event) {
89
- var _a;
90
- null === (_a = this.onCloseCallback) || void 0 === _a || _a.call(this, event), this.emitUnifiedMessage({
91
- type: "close",
92
- event: event
93
- });
94
- }
95
- closeFromConnectionEvent() {
96
- const closeEvent = new Event("close");
97
- this.emitCloseEvent(closeEvent), this.close();
98
- }
99
- shouldCloseFromMessage(rawData, data) {
100
- var _a;
101
- return !!(null === (_a = this.connectionClose) || void 0 === _a ? void 0 : _a.message) && (rawData === this.connectionClose.message || data === this.connectionClose.message);
102
- }
103
- emitUnifiedCustomMessage(customEvent, data, event) {
104
- this.emitUnifiedMessage({
105
- type: customEvent.name,
106
- data: data,
107
- event: event
108
- });
109
- }
110
- /**
111
- * Attach custom event listeners to the SSE connection
112
- */ attachCustomEventListener(customEvent) {
113
- var _a;
114
- if (!this.sseConnection) return;
115
- const handler = eventInfo => {
116
- var _a, _b;
117
- const data = this.parseEventData(eventInfo.data);
118
- null === (_a = customEvent.handler) || void 0 === _a || _a.call(customEvent, data),
119
- this.emitUnifiedCustomMessage(customEvent, data, eventInfo), (null === (_b = this.connectionClose) || void 0 === _b ? void 0 : _b.event) === customEvent.name && this.closeFromConnectionEvent();
120
- }, currentHandlers = null !== (_a = this.customEventHandlers.get(customEvent.name)) && void 0 !== _a ? _a : [];
121
- currentHandlers.push(handler), this.customEventHandlers.set(customEvent.name, currentHandlers),
122
- this.sseConnection.addEventListener(customEvent.name, handler);
123
- }
124
- /**
125
- * Attach custom event listeners to the SSE connection
126
- */ attachCustomEventListeners(customEvents) {
127
- const events = Array.isArray(customEvents) ? customEvents : [ customEvents ];
128
- for (const event of events) this.attachCustomEventListener(event);
129
- }
130
- /**
131
- * Clean up listeners
132
- */ detachAllEventListeners(connection) {
133
- connection.removeEventListener("message", this.onMessage), connection.removeEventListener("error", this.onError),
134
- connection.removeEventListener("open", this.onOpen);
135
- for (const [eventName, handlers] of this.customEventHandlers.entries()) for (const handler of handlers) connection.removeEventListener(eventName, handler);
136
- this.customEventHandlers.clear();
137
- }
138
- }
1
+ export { S as SSEConnection } from "../../chunks/SSEConnection-Dj9P0SWE.mjs";
139
2
 
140
- export { SSEConnection };
3
+ export { W as WSConnection } from "../../chunks/WSConnection-DlYSitff.mjs";
4
+
5
+ import "../../chunks/tslib.es6-c-7TIv71.mjs";
@@ -5,5 +5,5 @@ export { useToolTip } from './useToolTip/useToolTip';
5
5
  export { type KeyboardShortcut, type KeyboardShortcuts, useKeyboardShortcuts, } from './useKeyboardShortcuts/useKeyboardShortcuts';
6
6
  export { useLastUpdated } from './useLastUpdated/useLastUpdated';
7
7
  export { useLocalStore } from './useLocalStore/useLocalStore';
8
- export { useWindow, FormFactor, type BreakPoints } from './useWindow/useWindow';
8
+ export { useWindow, FormFactor, type BreakPoints, type WindowGeolocation, type WindowGeolocationError, } from './useWindow/useWindow';
9
9
  export { useObserveResize } from './useObserveResize/useObserveResize';
@@ -12,6 +12,20 @@ export declare enum FormFactor {
12
12
  * Breakpoint type matching form factor to width value
13
13
  */
14
14
  export type BreakPoints = Record<FormFactor, number>;
15
+ export type WindowGeolocation = {
16
+ latitude: number;
17
+ longitude: number;
18
+ accuracy: number;
19
+ altitude: number | null;
20
+ altitudeAccuracy: number | null;
21
+ heading: number | null;
22
+ speed: number | null;
23
+ timestamp: number;
24
+ };
25
+ export type WindowGeolocationError = {
26
+ code: number;
27
+ message: string;
28
+ };
15
29
  export declare function useWindow(breakpoints?: BreakPoints, top?: boolean): {
16
30
  viewportWidth: number | null;
17
31
  viewportHeight: number | null;
@@ -21,4 +35,9 @@ export declare function useWindow(breakpoints?: BreakPoints, top?: boolean): {
21
35
  isAppleDevice: boolean;
22
36
  formFactor: FormFactor;
23
37
  dpr: 2 | 1 | 3;
38
+ geolocationSupported: boolean;
39
+ location: WindowGeolocation | null;
40
+ locationError: Error | null;
41
+ gettingLocation: boolean;
42
+ requestGeolocation: () => void;
24
43
  };
@@ -2,7 +2,7 @@ export type { ToolTip, ToolTipInfo } from './components/sharedTypes';
2
2
  export { ToolTipType } from './components/sharedTypes';
3
3
  export { light, dark, lightTheme, darkTheme, motion, elevations, Elevation, } from './theme';
4
4
  export type { SliceTheme, Colors, Type, Corners, Elevations, } from './theme';
5
- export { type KeyboardShortcut, type KeyboardShortcuts, type BreakPoints, useKeyboardShortcuts, useTheme, useObserveTheme, useToolTip, useLastUpdated, useLocalStore, useWindow, useDoubleClick, useObserveResize, } from './hooks';
5
+ export { type KeyboardShortcut, type KeyboardShortcuts, type BreakPoints, type WindowGeolocation, type WindowGeolocationError, useKeyboardShortcuts, useTheme, useObserveTheme, useToolTip, useLastUpdated, useLocalStore, useWindow, useDoubleClick, useObserveResize, } from './hooks';
6
6
  export { Avatar } from './components/Avatar/index';
7
7
  export type { AvatarProps } from './components/Avatar/index';
8
8
  export { AvatarGroup } from './components/AvatarGroup';
@@ -0,0 +1,17 @@
1
+ import type { UnifiedMessageEvent, WSConnection, WSConnectionOptions } from '../../utils';
2
+ export type WSStoreConnectionOptions = Omit<WSConnectionOptions<unknown>, 'unifiedMessages'> & {
3
+ onMessageCallback?: (message: UnifiedMessageEvent<unknown>) => void;
4
+ };
5
+ export interface WSStoreConnection {
6
+ name: string;
7
+ connection: WSConnection<unknown>;
8
+ }
9
+ export interface WSStore {
10
+ connections: WSStoreConnection[];
11
+ message: UnifiedMessageEvent<unknown> | null;
12
+ closedConnection: string | null;
13
+ actions: {
14
+ addConnection: (name: string, options: WSStoreConnectionOptions) => WSStoreConnection;
15
+ removeConnection: (name: string) => void;
16
+ };
17
+ }
@@ -0,0 +1,2 @@
1
+ export { useWSStore, useWS, useConnectionClose, useConnectionMessage, useIsConnected, useMessage, useWSActions, useLastWSMessage, } from './wsStore';
2
+ export type { WSStore, WSStoreConnection, WSStoreConnectionOptions, } from './_types';
@@ -0,0 +1,19 @@
1
+ import { type UnifiedMessageEvent } from '../../utils';
2
+ import type { WSStore, WSStoreConnectionOptions } from './_types';
3
+ export declare const useWSStore: import("zustand").UseBoundStore<import("zustand").StoreApi<WSStore>>;
4
+ export declare const useWS: () => {
5
+ addConnection: (name: string, options: WSStoreConnectionOptions) => import("./_types").WSStoreConnection;
6
+ removeConnection: (name: string) => void;
7
+ };
8
+ export declare const useConnectionClose: () => string | null;
9
+ export declare const useConnectionMessage: (connection: string) => UnifiedMessageEvent<unknown> | null;
10
+ export declare const useIsConnected: (connection?: string) => boolean;
11
+ export declare function useMessage(): UnifiedMessageEvent<unknown> | null;
12
+ export declare function useMessage<T = unknown>(type: 'message', connection?: string): T | string | Blob | ArrayBuffer | null;
13
+ export declare function useMessage(type: 'open' | 'error' | 'close', connection?: string): Event | ErrorEvent | CloseEvent | null;
14
+ export declare function useMessage<T = unknown>(type: string, connection?: string): T | string | Blob | ArrayBuffer | null;
15
+ export declare const useWSActions: {
16
+ addConnection: (name: string, options: WSStoreConnectionOptions) => import("./_types").WSStoreConnection;
17
+ removeConnection: (name: string) => void;
18
+ };
19
+ export declare const useLastWSMessage: () => UnifiedMessageEvent<unknown> | null;
@@ -1,3 +1,4 @@
1
+ import type { WindowGeolocation } from '../../hooks/useWindow/useWindow';
1
2
  export type WindowStore = {
2
3
  formFactor: FormFactor;
3
4
  dpr: 1 | 2 | 3;
@@ -7,8 +8,12 @@ export type WindowStore = {
7
8
  height: string;
8
9
  viewportWidth: number;
9
10
  viewportHeight: number;
11
+ location: WindowGeolocation | null;
12
+ locationError: Error | null;
13
+ gettingLocation: boolean;
10
14
  actions: {
11
15
  initialize: () => () => void;
16
+ getLocation: () => Promise<WindowGeolocation>;
12
17
  };
13
18
  };
14
19
  /**
@@ -1,2 +1,3 @@
1
- export { useWindowStore } from './windowStore';
2
- export { FormFactor, type BreakPoints, type WindowStore, } from './_types';
1
+ export { useWindowStore, useFormFactor, useViewportWidth, useViewportHeight, useIsAppleDevice, useIsTouchDevice, useIsElectron, useDpr, useLocation, useLocationError, useGettingLocation, useInitializeWindow, useGetLocation, formFactor, viewportWidth, viewportHeight, isAppleDevice, isTouchDevice, isElectron, dpr, location, locationError, gettingLocation, } from './windowStore';
2
+ export { FormFactor, type BreakPoints, type WindowStore } from './_types';
3
+ export type { WindowGeolocation, WindowGeolocationError, } from '../../hooks/useWindow/useWindow';
@@ -1,3 +1,4 @@
1
+ import type { WindowGeolocation } from '../../hooks/useWindow/useWindow';
1
2
  import { FormFactor, type WindowStore } from './_types';
2
3
  export declare const useWindowStore: import("zustand").UseBoundStore<import("zustand").StoreApi<WindowStore>>;
3
4
  export declare const useFormFactor: () => FormFactor;
@@ -7,7 +8,11 @@ export declare const useIsAppleDevice: () => boolean;
7
8
  export declare const useIsTouchDevice: () => boolean;
8
9
  export declare const useIsElectron: () => boolean;
9
10
  export declare const useDpr: () => 2 | 1 | 3;
11
+ export declare const useLocation: () => WindowGeolocation | null;
12
+ export declare const useLocationError: () => Error | null;
13
+ export declare const useGettingLocation: () => boolean;
10
14
  export declare const useInitializeWindow: () => () => () => void;
15
+ export declare const useGetLocation: () => () => Promise<WindowGeolocation>;
11
16
  export declare const formFactor: () => FormFactor;
12
17
  export declare const viewportWidth: () => number;
13
18
  export declare const viewportHeight: () => number;
@@ -15,3 +20,6 @@ export declare const isAppleDevice: () => boolean;
15
20
  export declare const isTouchDevice: () => boolean;
16
21
  export declare const isElectron: () => boolean;
17
22
  export declare const dpr: () => 2 | 1 | 3;
23
+ export declare const location: () => WindowGeolocation | null;
24
+ export declare const locationError: () => Error | null;
25
+ export declare const gettingLocation: () => boolean;
@@ -1,4 +1,4 @@
1
1
  export { copyToClipboard } from './functions/misc';
2
2
  export { tintFromColor, addOpacity } from './functions/colors';
3
- export { SSEConnection } from './objects';
4
- export type { SSECustomEvent, SSEConnectionCloseOption, SSEConnectionOptions, SSEEventMap, SSEUnifiedBuiltInMessage, SSEUnifiedCustomMessage, SSEUnifiedMessage, } from './objects';
3
+ export { SSEConnection, WSConnection } from './objects';
4
+ export type { SSECustomEvent, SSEConnectionCloseOption, SSEConnectionOptions, SSEEventMap, SSEUnifiedBuiltInMessage, SSEUnifiedCustomMessage, SSEUnifiedMessage, UnifiedMessageEvent, WSConnectionOptions, } from './objects';
@@ -0,0 +1,147 @@
1
+ type WSRawData = string | Blob | ArrayBuffer;
2
+ type WSParsedData<TMessage> = TMessage | WSRawData;
3
+ export type UnifiedMessageEvent<TMessage> = {
4
+ type: 'message';
5
+ data: WSParsedData<TMessage>;
6
+ event: MessageEvent;
7
+ } | {
8
+ type: 'open';
9
+ event: Event;
10
+ } | {
11
+ type: 'close';
12
+ event: CloseEvent;
13
+ } | {
14
+ type: 'error';
15
+ event: ErrorEvent;
16
+ };
17
+ type WSStandardMessageCallback<TMessage> = (data: WSParsedData<TMessage>) => void;
18
+ type WSUnifiedMessageCallback<TMessage> = (message: UnifiedMessageEvent<TMessage>) => void;
19
+ interface WSConnectionOptionsBase {
20
+ url: string;
21
+ autoReconnect?: boolean;
22
+ reconnectInterval?: number;
23
+ reconnectAttempts?: number;
24
+ reconnectFalloff?: boolean;
25
+ keepAlive?: boolean;
26
+ keepAliveInterval?: number;
27
+ token?: string | (() => Promise<string>);
28
+ onOpenCallback?: (event: Event) => void;
29
+ onCloseCallback?: (event: CloseEvent) => void;
30
+ onErrorCallback?: (error: ErrorEvent) => void;
31
+ }
32
+ interface WSConnectionUnifiedOptions<TMessage = unknown> extends WSConnectionOptionsBase {
33
+ unifiedMessages: true;
34
+ onMessageCallback?: WSUnifiedMessageCallback<TMessage>;
35
+ }
36
+ interface WSConnectionStandardOptions<TMessage = unknown> extends WSConnectionOptionsBase {
37
+ unifiedMessages?: false;
38
+ onMessageCallback?: WSStandardMessageCallback<TMessage>;
39
+ }
40
+ export type WSConnectionOptions<TMessage = unknown> = WSConnectionStandardOptions<TMessage> | WSConnectionUnifiedOptions<TMessage>;
41
+ export declare class WSConnection<TMessage = unknown> {
42
+ private readonly url;
43
+ private readonly autoReconnect;
44
+ private readonly reconnectInterval;
45
+ private readonly reconnectAttempts;
46
+ private readonly reconnectFalloff;
47
+ private readonly keepAlive;
48
+ private readonly keepAliveInterval;
49
+ private readonly unifiedMessages;
50
+ private readonly token;
51
+ private readonly onMessageCallback?;
52
+ private readonly onOpenCallback?;
53
+ private readonly onCloseCallback?;
54
+ private readonly onErrorCallback?;
55
+ private socket;
56
+ private keepAliveTimer;
57
+ private reconnectIntervalTimer;
58
+ private reconnectAttemptsCount;
59
+ private manuallyClosed;
60
+ get connected(): boolean;
61
+ get connection(): WebSocket | null;
62
+ constructor(options: WSConnectionOptions<TMessage>);
63
+ /**
64
+ * Gracefully handle sending messages
65
+ */
66
+ send(message: unknown): void;
67
+ /**
68
+ * Gracefully expose socket close
69
+ */
70
+ close(closeEvent: {
71
+ code: number;
72
+ reason: string;
73
+ }): void;
74
+ /**
75
+ * Emit the parsed message content for standard mode
76
+ */
77
+ private emitParsedMessage;
78
+ /**
79
+ * Emit a unified message if the unified flag is on
80
+ */
81
+ private emitUnifiedMessage;
82
+ /**
83
+ * Emit error
84
+ */
85
+ private emitErrorEvent;
86
+ /**
87
+ * Safe JSON parse message content
88
+ */
89
+ private parseEventData;
90
+ /**
91
+ * Open handler
92
+ */
93
+ private readonly onOpen;
94
+ /**
95
+ * Message handler
96
+ */
97
+ private readonly onMessage;
98
+ /**
99
+ * Close handler with the reconnection logic as needed
100
+ */
101
+ private readonly onClose;
102
+ /**
103
+ * Error handler
104
+ */
105
+ private readonly onError;
106
+ /**
107
+ * Attach socket listeners
108
+ */
109
+ private attachEventListeners;
110
+ /**
111
+ * set keep alive pings
112
+ */
113
+ private setKeepAlive;
114
+ /**
115
+ * Clear keep alive pings
116
+ */
117
+ private clearKeepAliveTimer;
118
+ /**
119
+ * Clear reconnect timer
120
+ */
121
+ private clearReconnectTimer;
122
+ /**
123
+ * detach all event listeners
124
+ */
125
+ private detachEventListeners;
126
+ /**
127
+ * Connect the socket
128
+ */
129
+ private connect;
130
+ /**
131
+ * Reconnect logic
132
+ */
133
+ private reconnect;
134
+ /**
135
+ * Calculate reconnect delay with fall off
136
+ */
137
+ private getReconnectDelay;
138
+ /**
139
+ * Determine if should reconnect based on the close event and props
140
+ */
141
+ private shouldReconnect;
142
+ /**
143
+ * Internal close socket - does not reset retry logic
144
+ */
145
+ private closeSocket;
146
+ }
147
+ export {};
@@ -1,2 +1,4 @@
1
1
  export { SSEConnection } from './SSEConnection/SSEConnection';
2
+ export { WSConnection } from './WSConnection/WSConnection';
2
3
  export type { SSECustomEvent, SSEConnectionCloseOption, SSEConnectionOptions, SSEEventMap, SSEUnifiedBuiltInMessage, SSEUnifiedCustomMessage, SSEUnifiedMessage, } from './SSEConnection/SSEConnection';
4
+ export type { UnifiedMessageEvent, WSConnectionOptions, } from './WSConnection/WSConnection';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apple-pie/slice",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.mjs",
6
6
  "exports": {
@@ -1,70 +0,0 @@
1
- "use strict";
2
-
3
- var FormFactor, zustand = require("zustand");
4
-
5
- /**
6
- * Form factor names
7
- */ exports.FormFactor = void 0, (FormFactor = exports.FormFactor || (exports.FormFactor = {})).Mobile = "mobile",
8
- FormFactor.Tablet = "tablet", FormFactor.Desktop = "desktop", FormFactor.DesktopL = "desktopL",
9
- FormFactor.DesktopXL = "desktopXL";
10
-
11
- /**
12
- * Use bootstrap breakpoints
13
- */
14
- const bootstrapBreakPoints = {
15
- [exports.FormFactor.Mobile]: 576,
16
- [exports.FormFactor.Tablet]: 768,
17
- [exports.FormFactor.Desktop]: 992,
18
- [exports.FormFactor.DesktopL]: 1200,
19
- [exports.FormFactor.DesktopXL]: 1400
20
- }, orderedBps = Object.entries(bootstrapBreakPoints).sort((a, b) => -b[1] - a[1]), getFormFactor = width => {
21
- if (!width || width <= 0) return exports.FormFactor.Mobile;
22
- for (const [formFactor, breakpoint] of orderedBps) if (width >= breakpoint) return formFactor;
23
- return exports.FormFactor.Mobile;
24
- }, initialSize = processWindowSize(), useWindowStore = zustand.create((set, get) => {
25
- var _a;
26
- return {
27
- formFactor: initialSize.formFactor,
28
- viewportWidth: initialSize.viewportWidth,
29
- viewportHeight: initialSize.viewportHeight,
30
- height: initialSize.height,
31
- isElectron: checkElectron(),
32
- isAppleDevice: navigator.platform.startsWith("Mac") || "iPhone" === navigator.platform,
33
- isTouchDevice: "ontouchstart" in globalThis || navigator.maxTouchPoints > 0,
34
- dpr: null !== (_a = Math.min(Math.ceil(window.devicePixelRatio), 3)) && void 0 !== _a ? _a : 1,
35
- actions: {
36
- initialize: () => {
37
- var _a;
38
- const win = null !== (_a = globalThis.top) && void 0 !== _a ? _a : globalThis;
39
- return null == win || win.addEventListener("resize", handleResize), () => null == win ? void 0 : win.removeEventListener("resize", handleResize);
40
- }
41
- }
42
- };
43
- });
44
-
45
- function checkElectron() {
46
- return navigator.userAgent.toLowerCase().includes("electron/");
47
- }
48
-
49
- function handleResize() {
50
- const {formFactor: formFactor, viewportWidth: viewportWidth, viewportHeight: viewportHeight, height: height} = processWindowSize();
51
- useWindowStore.setState({
52
- formFactor: formFactor,
53
- viewportWidth: viewportWidth,
54
- viewportHeight: viewportHeight,
55
- height: height
56
- });
57
- }
58
-
59
- function processWindowSize(top = !0) {
60
- var _a, _b, _c;
61
- const viewport = null !== (_a = globalThis.top) && void 0 !== _a ? _a : globalThis, touch = "ontouchstart" in globalThis || navigator.maxTouchPoints > 0, windowWidth = null !== (_b = null == viewport ? void 0 : viewport.innerWidth) && void 0 !== _b ? _b : -1, windowHeight = null !== (_c = null == viewport ? void 0 : viewport.innerHeight) && void 0 !== _c ? _c : -1;
62
- return {
63
- formFactor: getFormFactor(windowWidth),
64
- viewportWidth: windowWidth,
65
- viewportHeight: windowHeight,
66
- height: viewport && touch ? `${windowHeight}px` : "100vh"
67
- };
68
- }
69
-
70
- exports.useWindowStore = useWindowStore;