@holo-js/flux-svelte 0.1.3

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.
@@ -0,0 +1,26 @@
1
+ import { Readable } from 'svelte/store';
2
+ import { FluxClient, FluxConnectionStatus, FluxListenerControls } from '@holo-js/flux';
3
+ import { GeneratedBroadcastManifest, BroadcastPayloadFor } from '@holo-js/broadcast';
4
+
5
+ interface FluxHelperOptions<TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest> {
6
+ readonly client?: FluxClient<TManifest>;
7
+ readonly onUnmount?: (cleanup: () => void) => void;
8
+ }
9
+ interface FluxConnectionStatusHelperOptions<TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest> extends FluxHelperOptions<TManifest> {
10
+ readonly onChange?: (status: FluxConnectionStatus) => void;
11
+ }
12
+ interface FluxPresenceHelperCallbacks<TMember = unknown> {
13
+ readonly onHere?: (members: readonly TMember[]) => void;
14
+ }
15
+ type FluxPresenceHelperState<TMember = unknown> = FluxListenerControls & {
16
+ readonly members: Readable<readonly TMember[]>;
17
+ };
18
+ declare function useFlux<TEvent extends string, TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(channel: string, events: TEvent | readonly TEvent[], callback: (payload: BroadcastPayloadFor<TEvent>) => void, options?: FluxHelperOptions<TManifest>): FluxListenerControls;
19
+ declare function useFluxPublic<TEvent extends string, TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(channel: string, events: TEvent | readonly TEvent[], callback: (payload: BroadcastPayloadFor<TEvent>) => void, options?: FluxHelperOptions<TManifest>): FluxListenerControls;
20
+ declare function useFluxPrivate<TEvent extends string, TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(channel: string, events: TEvent | readonly TEvent[], callback: (payload: BroadcastPayloadFor<TEvent>) => void, options?: FluxHelperOptions<TManifest>): FluxListenerControls;
21
+ declare function useFluxPresence<TMember = unknown, TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(channel: string, callbacks?: FluxPresenceHelperCallbacks<TMember>, options?: FluxHelperOptions<TManifest>): FluxPresenceHelperState<TMember>;
22
+ declare function useFluxNotification<TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(channel: string, callback: (payload: unknown) => void, options?: FluxHelperOptions<TManifest>): FluxListenerControls;
23
+ declare function useFluxModel<TEvent extends string, TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(channel: string, events: TEvent | readonly TEvent[], callback: (payload: BroadcastPayloadFor<TEvent>) => void, options?: FluxHelperOptions<TManifest>): FluxListenerControls;
24
+ declare function useFluxConnectionStatus<TManifest extends GeneratedBroadcastManifest = GeneratedBroadcastManifest>(options?: FluxConnectionStatusHelperOptions<TManifest>): Readable<FluxConnectionStatus>;
25
+
26
+ export { type FluxConnectionStatusHelperOptions, type FluxHelperOptions, type FluxPresenceHelperCallbacks, type FluxPresenceHelperState, useFlux, useFluxConnectionStatus, useFluxModel, useFluxNotification, useFluxPresence, useFluxPrivate, useFluxPublic };
package/dist/index.mjs ADDED
@@ -0,0 +1,123 @@
1
+ // src/index.ts
2
+ import { onDestroy } from "svelte";
3
+ import { readable, writable } from "svelte/store";
4
+ import { getFluxClient } from "@holo-js/flux";
5
+ function resolveClient(options) {
6
+ return options.client ?? getFluxClient();
7
+ }
8
+ function registerCleanup(options, cleanup) {
9
+ const runCleanup = () => {
10
+ cleanup();
11
+ };
12
+ let registered = false;
13
+ try {
14
+ onDestroy(runCleanup);
15
+ registered = true;
16
+ } catch {
17
+ registered = false;
18
+ }
19
+ if (!registered) {
20
+ options.onUnmount?.(runCleanup);
21
+ }
22
+ }
23
+ function controlsFromSubscription(subscription) {
24
+ const controls = {
25
+ leave: () => {
26
+ subscription.leave();
27
+ },
28
+ leaveChannel: () => {
29
+ subscription.leaveChannel();
30
+ },
31
+ listen: () => {
32
+ subscription.listen();
33
+ return controls;
34
+ },
35
+ stopListening: () => {
36
+ subscription.stopListening();
37
+ }
38
+ };
39
+ return Object.freeze(controls);
40
+ }
41
+ function subscribeWithEvents(subscription, events, callback) {
42
+ return subscription.listen(
43
+ events,
44
+ callback
45
+ );
46
+ }
47
+ function useFlux(channel, events, callback, options = {}) {
48
+ const subscription = subscribeWithEvents(
49
+ resolveClient(options).private(channel),
50
+ events,
51
+ callback
52
+ );
53
+ registerCleanup(options, () => {
54
+ subscription.leaveChannel();
55
+ });
56
+ return controlsFromSubscription(subscription);
57
+ }
58
+ function useFluxPublic(channel, events, callback, options = {}) {
59
+ const subscription = subscribeWithEvents(
60
+ resolveClient(options).channel(channel),
61
+ events,
62
+ callback
63
+ );
64
+ registerCleanup(options, () => {
65
+ subscription.leaveChannel();
66
+ });
67
+ return controlsFromSubscription(subscription);
68
+ }
69
+ function useFluxPrivate(channel, events, callback, options = {}) {
70
+ return useFlux(channel, events, callback, options);
71
+ }
72
+ function useFluxPresence(channel, callbacks = {}, options = {}) {
73
+ const subscription = resolveClient(options).presence(channel);
74
+ callbacks.onHere?.(subscription.members);
75
+ const members = writable(subscription.members);
76
+ const stop = subscription.__onPresenceChange?.((nextMembers) => {
77
+ const typedMembers = nextMembers;
78
+ callbacks.onHere?.(typedMembers);
79
+ members.set(typedMembers);
80
+ });
81
+ registerCleanup(options, () => {
82
+ stop?.();
83
+ subscription.leaveChannel();
84
+ });
85
+ return Object.freeze({
86
+ ...controlsFromSubscription(subscription),
87
+ members
88
+ });
89
+ }
90
+ function useFluxNotification(channel, callback, options = {}) {
91
+ const subscription = resolveClient(options).private(channel).notification(callback);
92
+ registerCleanup(options, () => {
93
+ subscription.leaveChannel();
94
+ });
95
+ return controlsFromSubscription(subscription);
96
+ }
97
+ function useFluxModel(channel, events, callback, options = {}) {
98
+ return useFluxPrivate(channel, events, callback, options);
99
+ }
100
+ function useFluxConnectionStatus(options = {}) {
101
+ const client = resolveClient(options);
102
+ const status = writable(client.getStatus());
103
+ const unsubscribe = client.onStatusChange((nextStatus) => {
104
+ options.onChange?.(nextStatus);
105
+ status.set(nextStatus);
106
+ });
107
+ registerCleanup(options, unsubscribe);
108
+ return readable(client.getStatus(), (set) => {
109
+ const stop = status.subscribe(set);
110
+ return () => {
111
+ stop();
112
+ };
113
+ });
114
+ }
115
+ export {
116
+ useFlux,
117
+ useFluxConnectionStatus,
118
+ useFluxModel,
119
+ useFluxNotification,
120
+ useFluxPresence,
121
+ useFluxPrivate,
122
+ useFluxPublic
123
+ };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@holo-js/flux-svelte",
3
+ "version": "0.1.3",
4
+ "description": "Holo-JS Framework - Svelte and SvelteKit Flux helper skeletons",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "default": "./dist/index.mjs"
12
+ }
13
+ },
14
+ "main": "./dist/index.mjs",
15
+ "types": "./dist/index.d.ts",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "stub": "tsup",
22
+ "typecheck": "tsc -p tsconfig.json --noEmit",
23
+ "test": "vitest --run"
24
+ },
25
+ "dependencies": {
26
+ "@holo-js/broadcast": "^0.1.3",
27
+ "@holo-js/flux": "^0.1.3"
28
+ },
29
+ "peerDependencies": {
30
+ "svelte": "^5.16.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.10.2",
34
+ "svelte": "^5.16.0",
35
+ "tsup": "^8.3.5",
36
+ "typescript": "^5.7.2",
37
+ "vitest": "^2.1.8"
38
+ }
39
+ }