react-websocket 2.2.0 → 3.1.0
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.
- package/README.md +133 -49
- package/dist/core.cjs +594 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +435 -0
- package/dist/core.d.ts +435 -0
- package/dist/core.js +564 -0
- package/dist/core.js.map +1 -0
- package/dist/index.cjs +164 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +541 -0
- package/dist/index.d.ts +541 -0
- package/dist/index.js +134 -0
- package/dist/index.js.map +1 -0
- package/package.json +116 -27
- package/babel.config.json +0 -6
- package/build/index.js +0 -2
- package/build/index.map +0 -1
- package/index.jsx +0 -117
- package/webpack.config.js +0 -21
- package/webpack.prod.config.js +0 -40
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/react.ts"],"sourcesContent":["export * from './core';\nexport {\n useWebSocket,\n useWebSocketEvent,\n useWebSocketState,\n useWebSocketStatus,\n useWebSocketTopic\n} from './react';\nexport type { UseWebSocketOptions, UseWebSocketResult, WebSocketHandlers } from './react';\n","import { useEffect, useInsertionEffect, useMemo, useRef, useSyncExternalStore } from 'react';\n// Import the client through the `core` entry: the build keeps it external, so both entries\n// share one copy of it (and of `MessageError`).\nimport { createWebSocket } from './core';\nimport type { WebSocketState } from './state';\nimport type { WebSocketTopics } from './topics';\nimport type {\n CloseInfo,\n EventMap,\n Snapshot,\n Status,\n WebSocketClient,\n WebSocketOptions\n} from './types';\n\n/**\n * Per-component event handlers. They always see the component's latest props and\n * state, and changing them never reconnects.\n */\nexport interface WebSocketHandlers<In> {\n /** The socket opened (initially or after a reconnect). */\n onOpen?: (event: Event) => void;\n /** A message arrived and passed `parse`/`json` and `schema`. */\n onMessage?: (message: In, event: MessageEvent) => void;\n /** A socket closed. Called whether or not it will be retried. */\n onClose?: (close: CloseInfo) => void;\n /** A socket error `Event`, a `MessageError`, or an `Error` from the constructor or `url` function. */\n onError?: (error: Event | Error) => void;\n /**\n * `false` releases this component's hold on the connection and stops its handlers.\n * The connection closes once nothing else holds it.\n * @default true\n */\n enabled?: boolean;\n}\n\n/** Options for `useWebSocket(url, options)`: connection options plus handlers. */\nexport interface UseWebSocketOptions<In, Out>\n extends WebSocketOptions<In, Out>, WebSocketHandlers<In> {}\n\n/** What `useWebSocket` returns: the current {@link Snapshot} plus stable actions. */\nexport interface UseWebSocketResult<In, Out> extends Snapshot<In> {\n /** Send now, or queue until open. Returns `true` if sent immediately. Stable identity. */\n send: (message: Out) => boolean;\n /** Close and stop reconnecting (for every component sharing the connection). Stable identity. */\n close: (code?: number, reason?: string) => void;\n /** Drop the socket and connect again right away. Stable identity. */\n reconnect: () => void;\n /** The underlying client, or `null` when the URL is `null`/`undefined`. */\n client: WebSocketClient<In, Out> | null;\n}\n\nconst IDLE: Snapshot<never> = Object.freeze({ status: 'idle', lastMessage: undefined, attempt: 0 });\nconst idleSnapshot = () => IDLE;\nconst idleStatus = (): Status => 'idle';\nconst noopSubscribe = () => () => {};\nconst noopSend = () => false;\nconst noop = () => {};\n\n// Same key as `ON_TEARDOWN` in ./client, which this entry must not import directly.\nconst ON_TEARDOWN = Symbol.for('react-websocket.onTeardown');\n\n// Hooks given the same URL (and protocols) share one connection.\nconst registry = new Map<string, WebSocketClient<any, any>>();\n\nfunction sharedClient<In, Out>(url: string, options: WebSocketOptions<In, Out>) {\n // Don't let server renders accumulate clients that can never be torn down.\n if (typeof window === 'undefined') return createWebSocket(url, options);\n const key = `${url}\\u0000${JSON.stringify(options.protocols ?? null)}`;\n let client = registry.get(key) as WebSocketClient<In, Out> | undefined;\n if (!client) {\n const created: WebSocketClient<In, Out> = createWebSocket(url, {\n ...options,\n [ON_TEARDOWN]: () => {\n if (registry.get(key) === created) registry.delete(key);\n }\n } as WebSocketOptions<In, Out>);\n registry.set(key, created);\n client = created;\n }\n return client;\n}\n\n/** Always-current value for use inside effects and event listeners (a `useEffectEvent` stand-in). */\nfunction useLatest<T>(value: T) {\n const ref = useRef(value);\n useInsertionEffect(() => {\n ref.current = value;\n });\n return ref;\n}\n\nfunction useHold(client: WebSocketClient<any, any> | null, enabled: boolean) {\n useEffect(() => {\n if (client && enabled) return client.acquire();\n }, [client, enabled]);\n}\n\n/**\n * Connect to a WebSocket and re-render with its status and latest message.\n *\n * - With a URL, every component using the same URL (and `protocols`) shares one\n * connection. Its options come from whichever component created it first.\n * - With a client from `createWebSocket()`, options are the client's; only handlers\n * and `enabled` apply here.\n * - With `null` or `undefined`, nothing connects and the status stays `idle`.\n *\n * The connection opens on mount and closes one tick after the last component using it\n * unmounts, so StrictMode and `<Activity>` don't open duplicate sockets.\n *\n * Re-renders on status changes and on every message. For high-frequency streams use\n * `useWebSocketEvent` and `useWebSocketStatus` instead.\n *\n * @example\n * ```tsx\n * const { status, lastMessage, send } = useWebSocket<Price, Order>('wss://api.example.com/prices', {\n * json: true,\n * onMessage: price => console.log(price)\n * });\n * ```\n */\nexport function useWebSocket<In = unknown, Out = unknown>(\n url: string | null | undefined,\n options?: UseWebSocketOptions<In, Out>\n): UseWebSocketResult<In, Out>;\nexport function useWebSocket<In, Out>(\n client: WebSocketClient<In, Out> | null | undefined,\n options?: WebSocketHandlers<In>\n): UseWebSocketResult<In, Out>;\nexport function useWebSocket<In, Out>(\n target: string | WebSocketClient<In, Out> | null | undefined,\n options: UseWebSocketOptions<In, Out> = {}\n): UseWebSocketResult<In, Out> {\n const client =\n target == null ? null : typeof target === 'string' ? sharedClient(target, options) : target;\n const enabled = options.enabled ?? true;\n\n const snapshot = useSyncExternalStore<Snapshot<In>>(\n client ? client.subscribe : noopSubscribe,\n client ? client.getSnapshot : idleSnapshot,\n idleSnapshot\n );\n\n const handlers = useLatest(options);\n useEffect(() => {\n if (!client || !enabled) return;\n const offs = [\n client.on('open', event => handlers.current.onOpen?.(event)),\n client.on('message', (message, event) => handlers.current.onMessage?.(message, event)),\n client.on('close', info => handlers.current.onClose?.(info)),\n client.on('error', error => handlers.current.onError?.(error))\n ];\n return () => offs.forEach(off => off());\n }, [client, enabled, handlers]);\n useHold(client, enabled);\n\n return {\n ...snapshot,\n send: client ? client.send : noopSend,\n close: client ? client.close : noop,\n reconnect: client ? client.reconnect : noop,\n client\n };\n}\n\n/**\n * Listen to a client's events without re-rendering the component. The listener always\n * sees the latest props and state. Keeps the connection open while mounted.\n *\n * @example\n * ```tsx\n * useWebSocketEvent(chat, 'message', message => setMessages(list => [...list, message]));\n * ```\n */\nexport function useWebSocketEvent<In, K extends keyof EventMap<In>>(\n client: WebSocketClient<In, any> | null | undefined,\n type: K,\n listener: EventMap<In>[K]\n): void {\n const latest = useLatest(listener);\n useEffect(() => {\n if (!client) return;\n const off = client.on(type, ((...args: unknown[]) =>\n (latest.current as (...a: unknown[]) => void)(...args)) as EventMap<In>[K]);\n const release = client.acquire();\n return () => {\n off();\n release();\n };\n }, [client, type, latest]);\n}\n\n/**\n * The connection status of a client. Re-renders only when the status changes, not on\n * messages. Keeps the connection open while mounted.\n *\n * @example\n * ```tsx\n * const status = useWebSocketStatus(chat); // 'idle' | 'connecting' | 'open' | 'reconnecting' | 'closed'\n * ```\n */\nexport function useWebSocketStatus(client: WebSocketClient<any, any> | null | undefined): Status {\n const status = useSyncExternalStore(\n client ? client.subscribe : noopSubscribe,\n client ? () => client.getSnapshot().status : idleStatus,\n idleStatus\n );\n useHold(client ?? null, true);\n return status;\n}\n\nconst identity = <T>(value: T) => value;\n\n/**\n * Read state built from messages by `createWebSocketState`. Re-renders only when the\n * selected value changes (by `isEqual`, default `Object.is`), however often messages\n * arrive. Keeps the connection open while mounted.\n *\n * On the server, and during hydration, it reads from `initialState`.\n *\n * @example\n * ```tsx\n * const acme = useWebSocketState(priceState, state => state.ACME);\n * ```\n */\nexport function useWebSocketState<S>(store: WebSocketState<S>): S;\nexport function useWebSocketState<S, T>(\n store: WebSocketState<S>,\n selector: (state: S) => T,\n isEqual?: (a: T, b: T) => boolean\n): T;\nexport function useWebSocketState<S, T>(\n store: WebSocketState<S>,\n selector: (state: S) => T = identity as (state: S) => T,\n isEqual: (a: T, b: T) => boolean = Object.is\n): T {\n const [getSelection, getServerSelection] = useMemo(() => {\n // Return the previous selection while the state is unchanged or the result is equal,\n // so inline selectors that build objects don't re-render (or loop) on every message.\n const memoized = (read: () => S) => {\n let memo: { state: S; selection: T } | undefined;\n return () => {\n const state = read();\n if (memo && Object.is(memo.state, state)) return memo.selection;\n const selection = selector(state);\n if (memo && isEqual(memo.selection, selection)) {\n memo = { state, selection: memo.selection };\n return memo.selection;\n }\n memo = { state, selection };\n return selection;\n };\n };\n return [memoized(store.getState), memoized(() => store.initialState)] as const;\n }, [store, selector, isEqual]);\n\n const selection = useSyncExternalStore(store.subscribe, getSelection, getServerSelection);\n useHold(store.client, true);\n return selection;\n}\n\n/**\n * Subscribe to one topic (or several) while mounted, through a `createWebSocketTopics`\n * manager. Components holding the same topic share one subscription, and it is sent again\n * after every reconnect. Keeps the connection open while mounted. `null` holds nothing.\n *\n * @example\n * ```tsx\n * useWebSocketTopic(topics, `prices:${symbol}`);\n * useWebSocketTopic(topics, watchlist.map(symbol => `prices:${symbol}`));\n * ```\n */\nexport function useWebSocketTopic(\n topics: WebSocketTopics | null | undefined,\n topic: string | readonly string[] | null | undefined\n): void {\n // A stable key, so a new array with the same topics doesn't resubscribe.\n const key = topic == null ? null : JSON.stringify(typeof topic === 'string' ? [topic] : topic);\n useEffect(() => {\n if (!topics || key === null) return;\n const releases = (JSON.parse(key) as string[]).map(t => topics.acquire(t));\n return () => releases.forEach(release => release());\n }, [topics, key]);\n}\n"],"mappings":";;;AAAA,cAAc;;;ACAd,SAAS,WAAW,oBAAoB,SAAS,QAAQ,4BAA4B;AAGrF,SAAS,uBAAuB;AAiDhC,IAAM,OAAwB,OAAO,OAAO,EAAE,QAAQ,QAAQ,aAAa,QAAW,SAAS,EAAE,CAAC;AAClG,IAAM,eAAe,MAAM;AAC3B,IAAM,aAAa,MAAc;AACjC,IAAM,gBAAgB,MAAM,MAAM;AAAC;AACnC,IAAM,WAAW,MAAM;AACvB,IAAM,OAAO,MAAM;AAAC;AAGpB,IAAM,cAAc,uBAAO,IAAI,4BAA4B;AAG3D,IAAM,WAAW,oBAAI,IAAuC;AAE5D,SAAS,aAAsB,KAAa,SAAoC;AAE9E,MAAI,OAAO,WAAW,YAAa,QAAO,gBAAgB,KAAK,OAAO;AACtE,QAAM,MAAM,GAAG,GAAG,KAAS,KAAK,UAAU,QAAQ,aAAa,IAAI,CAAC;AACpE,MAAI,SAAS,SAAS,IAAI,GAAG;AAC7B,MAAI,CAAC,QAAQ;AACX,UAAM,UAAoC,gBAAgB,KAAK;AAAA,MAC7D,GAAG;AAAA,MACH,CAAC,WAAW,GAAG,MAAM;AACnB,YAAI,SAAS,IAAI,GAAG,MAAM,QAAS,UAAS,OAAO,GAAG;AAAA,MACxD;AAAA,IACF,CAA8B;AAC9B,aAAS,IAAI,KAAK,OAAO;AACzB,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAGA,SAAS,UAAa,OAAU;AAC9B,QAAM,MAAM,OAAO,KAAK;AACxB,qBAAmB,MAAM;AACvB,QAAI,UAAU;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAEA,SAAS,QAAQ,QAA0C,SAAkB;AAC3E,YAAU,MAAM;AACd,QAAI,UAAU,QAAS,QAAO,OAAO,QAAQ;AAAA,EAC/C,GAAG,CAAC,QAAQ,OAAO,CAAC;AACtB;AAiCO,SAAS,aACd,QACA,UAAwC,CAAC,GACZ;AAC7B,QAAM,SACJ,UAAU,OAAO,OAAO,OAAO,WAAW,WAAW,aAAa,QAAQ,OAAO,IAAI;AACvF,QAAM,UAAU,QAAQ,WAAW;AAEnC,QAAM,WAAW;AAAA,IACf,SAAS,OAAO,YAAY;AAAA,IAC5B,SAAS,OAAO,cAAc;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,WAAW,UAAU,OAAO;AAClC,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,QAAS;AACzB,UAAM,OAAO;AAAA,MACX,OAAO,GAAG,QAAQ,WAAS,SAAS,QAAQ,SAAS,KAAK,CAAC;AAAA,MAC3D,OAAO,GAAG,WAAW,CAAC,SAAS,UAAU,SAAS,QAAQ,YAAY,SAAS,KAAK,CAAC;AAAA,MACrF,OAAO,GAAG,SAAS,UAAQ,SAAS,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC3D,OAAO,GAAG,SAAS,WAAS,SAAS,QAAQ,UAAU,KAAK,CAAC;AAAA,IAC/D;AACA,WAAO,MAAM,KAAK,QAAQ,SAAO,IAAI,CAAC;AAAA,EACxC,GAAG,CAAC,QAAQ,SAAS,QAAQ,CAAC;AAC9B,UAAQ,QAAQ,OAAO;AAEvB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,SAAS,OAAO,OAAO;AAAA,IAC7B,OAAO,SAAS,OAAO,QAAQ;AAAA,IAC/B,WAAW,SAAS,OAAO,YAAY;AAAA,IACvC;AAAA,EACF;AACF;AAWO,SAAS,kBACd,QACA,MACA,UACM;AACN,QAAM,SAAS,UAAU,QAAQ;AACjC,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,UAAM,MAAM,OAAO,GAAG,OAAO,IAAI,SAC9B,OAAO,QAAsC,GAAG,IAAI,EAAqB;AAC5E,UAAM,UAAU,OAAO,QAAQ;AAC/B,WAAO,MAAM;AACX,UAAI;AACJ,cAAQ;AAAA,IACV;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,MAAM,CAAC;AAC3B;AAWO,SAAS,mBAAmB,QAA8D;AAC/F,QAAM,SAAS;AAAA,IACb,SAAS,OAAO,YAAY;AAAA,IAC5B,SAAS,MAAM,OAAO,YAAY,EAAE,SAAS;AAAA,IAC7C;AAAA,EACF;AACA,UAAQ,UAAU,MAAM,IAAI;AAC5B,SAAO;AACT;AAEA,IAAM,WAAW,CAAI,UAAa;AAoB3B,SAAS,kBACd,OACA,WAA4B,UAC5B,UAAmC,OAAO,IACvC;AACH,QAAM,CAAC,cAAc,kBAAkB,IAAI,QAAQ,MAAM;AAGvD,UAAM,WAAW,CAAC,SAAkB;AAClC,UAAI;AACJ,aAAO,MAAM;AACX,cAAM,QAAQ,KAAK;AACnB,YAAI,QAAQ,OAAO,GAAG,KAAK,OAAO,KAAK,EAAG,QAAO,KAAK;AACtD,cAAMA,aAAY,SAAS,KAAK;AAChC,YAAI,QAAQ,QAAQ,KAAK,WAAWA,UAAS,GAAG;AAC9C,iBAAO,EAAE,OAAO,WAAW,KAAK,UAAU;AAC1C,iBAAO,KAAK;AAAA,QACd;AACA,eAAO,EAAE,OAAO,WAAAA,WAAU;AAC1B,eAAOA;AAAA,MACT;AAAA,IACF;AACA,WAAO,CAAC,SAAS,MAAM,QAAQ,GAAG,SAAS,MAAM,MAAM,YAAY,CAAC;AAAA,EACtE,GAAG,CAAC,OAAO,UAAU,OAAO,CAAC;AAE7B,QAAM,YAAY,qBAAqB,MAAM,WAAW,cAAc,kBAAkB;AACxF,UAAQ,MAAM,QAAQ,IAAI;AAC1B,SAAO;AACT;AAaO,SAAS,kBACd,QACA,OACM;AAEN,QAAM,MAAM,SAAS,OAAO,OAAO,KAAK,UAAU,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,KAAK;AAC7F,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,QAAQ,KAAM;AAC7B,UAAM,WAAY,KAAK,MAAM,GAAG,EAAe,IAAI,OAAK,OAAO,QAAQ,CAAC,CAAC;AACzE,WAAO,MAAM,SAAS,QAAQ,aAAW,QAAQ,CAAC;AAAA,EACpD,GAAG,CAAC,QAAQ,GAAG,CAAC;AAClB;","names":["selection"]}
|
package/package.json
CHANGED
|
@@ -1,28 +1,73 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-websocket",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Hooks-first WebSocket client for React: shared connections, auto-reconnect, typed messages, Suspense-ready",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./core": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/core.d.ts",
|
|
23
|
+
"default": "./dist/core.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/core.d.cts",
|
|
27
|
+
"default": "./dist/core.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"sideEffects": false,
|
|
6
36
|
"publishConfig": {
|
|
7
|
-
"
|
|
37
|
+
"access": "public"
|
|
8
38
|
},
|
|
9
39
|
"scripts": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"test
|
|
14
|
-
"
|
|
40
|
+
"build": "rm -rf dist && tsup",
|
|
41
|
+
"dev": "tsup --watch",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:watch": "vitest",
|
|
44
|
+
"test:coverage": "vitest run --coverage",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"lint": "eslint .",
|
|
47
|
+
"format": "prettier --write .",
|
|
48
|
+
"format:check": "prettier --check .",
|
|
49
|
+
"check:package": "npm run build && publint --strict && attw --pack . --profile node16",
|
|
50
|
+
"size": "npm run build && size-limit",
|
|
51
|
+
"docs:dev": "vitepress dev docs",
|
|
52
|
+
"docs:build": "vitepress build docs",
|
|
53
|
+
"docs:preview": "vitepress preview docs",
|
|
54
|
+
"example": "vite example",
|
|
55
|
+
"example:server": "python3 example/server.py",
|
|
56
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run check:package"
|
|
15
57
|
},
|
|
16
58
|
"repository": {
|
|
17
59
|
"type": "git",
|
|
18
|
-
"url": "git
|
|
60
|
+
"url": "git+https://github.com/mehmetkose/react-websocket.git"
|
|
19
61
|
},
|
|
20
62
|
"keywords": [
|
|
21
|
-
"reactjs",
|
|
22
|
-
"websocket",
|
|
23
63
|
"react",
|
|
24
|
-
"
|
|
64
|
+
"websocket",
|
|
65
|
+
"hooks",
|
|
66
|
+
"realtime",
|
|
67
|
+
"reconnect",
|
|
68
|
+
"suspense"
|
|
25
69
|
],
|
|
70
|
+
"author": "Mehmet Kose <mehmet@sourcream.uk> (https://sourcream.uk/)",
|
|
26
71
|
"maintainers": [
|
|
27
72
|
"Mehmet Kose <mehmet@sourcream.uk> (https://sourcream.uk/)"
|
|
28
73
|
],
|
|
@@ -31,25 +76,69 @@
|
|
|
31
76
|
"url": "https://github.com/mehmetkose/react-websocket/issues"
|
|
32
77
|
},
|
|
33
78
|
"homepage": "https://github.com/mehmetkose/react-websocket",
|
|
34
|
-
"example": {
|
|
35
|
-
"script": "example/component.jsx"
|
|
36
|
-
},
|
|
37
79
|
"peerDependencies": {
|
|
38
|
-
"react": "^
|
|
39
|
-
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
80
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
40
81
|
},
|
|
41
82
|
"devDependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"
|
|
46
|
-
"
|
|
83
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
84
|
+
"@eslint/js": "^10.0.1",
|
|
85
|
+
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
86
|
+
"@size-limit/preset-small-lib": "^14.2.0",
|
|
87
|
+
"@testing-library/react": "^16.3.3",
|
|
88
|
+
"@types/react": "^19.3.0",
|
|
89
|
+
"@types/react-dom": "^19.3.0",
|
|
90
|
+
"@vitejs/plugin-react": "^6.1.2",
|
|
91
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
92
|
+
"eslint": "^10.12.0",
|
|
93
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
94
|
+
"globals": "^17.13.0",
|
|
95
|
+
"jsdom": "^30.1.2",
|
|
96
|
+
"prettier": "^3.9.9",
|
|
97
|
+
"publint": "^0.3.25",
|
|
47
98
|
"react": "^19.3.0",
|
|
48
99
|
"react-dom": "^19.3.0",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
100
|
+
"size-limit": "^14.2.0",
|
|
101
|
+
"tsup": "^8.5.1",
|
|
102
|
+
"typescript": "^6.0.3",
|
|
103
|
+
"typescript-eslint": "^8.71.1",
|
|
104
|
+
"vite": "^8.3.4",
|
|
105
|
+
"vitepress": "^1.6.4",
|
|
106
|
+
"vitest": "^5.0.3"
|
|
51
107
|
},
|
|
52
|
-
"
|
|
53
|
-
|
|
108
|
+
"size-limit": [
|
|
109
|
+
{
|
|
110
|
+
"name": "react-websocket (useWebSocket)",
|
|
111
|
+
"path": "dist/index.js",
|
|
112
|
+
"import": "{ useWebSocket }",
|
|
113
|
+
"ignore": [
|
|
114
|
+
"react"
|
|
115
|
+
],
|
|
116
|
+
"limit": "3 kB"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "react-websocket/core (createWebSocket)",
|
|
120
|
+
"path": "dist/core.js",
|
|
121
|
+
"import": "{ createWebSocket }",
|
|
122
|
+
"ignore": [
|
|
123
|
+
"react"
|
|
124
|
+
],
|
|
125
|
+
"limit": "2.6 kB"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "react-websocket (topics + state hooks)",
|
|
129
|
+
"path": "dist/index.js",
|
|
130
|
+
"import": "{ useWebSocketTopic, useWebSocketState, createWebSocketTopics, createWebSocketState }",
|
|
131
|
+
"ignore": [
|
|
132
|
+
"react"
|
|
133
|
+
],
|
|
134
|
+
"limit": "1 kB"
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"overrides": {
|
|
138
|
+
"@docsearch/react": {
|
|
139
|
+
"react": "$react",
|
|
140
|
+
"react-dom": "$react-dom",
|
|
141
|
+
"@types/react": "$@types/react"
|
|
142
|
+
}
|
|
54
143
|
}
|
|
55
144
|
}
|
package/babel.config.json
DELETED
package/build/index.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports.Spinner=t(require("react")):e.Spinner=t(e.React)}(this,e=>(()=>{var t={694(e,t,o){"use strict";var s=o(925);function n(){}function r(){}r.resetWarningCache=n,e.exports=function(){function e(e,t,o,n,r,i){if(i!==s){var p=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw p.name="Invariant Violation",p}}function t(){return e}e.isRequired=e;var o={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:r,resetWarningCache:n};return o.PropTypes=o,o}},556(e,t,o){e.exports=o(694)()},925(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},442(t){"use strict";t.exports=e}};const o={};function s(e){const n=o[e];if(void 0!==n)return n.exports;const r=o[e]={exports:{}};return t[e](r,r.exports,s),r.exports}s.n=e=>{const t=e&&e.__esModule?()=>e.default:()=>e;return s.d(t,{a:t}),t},s.d=(e,t)=>{if(Array.isArray(t))for(var o=0;o<t.length;){var n=t[o++],r=t[o++],i=0===r?{enumerable:!0,value:t[o++]}:{enumerable:!0,get:r};s.o(e,n)||Object.defineProperty(e,n,i)}else for(var n in t)s.o(t,n)&&!s.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};let n={};return(()=>{"use strict";s.r(n);var e=s(442),t=s.n(e),o=s(556),r=s.n(o);class i extends t().Component{constructor(e){super(e),this.state={ws:window.WebSocket?new window.WebSocket(this.props.url,this.props.protocol):new window.MozWebSocket(this.props.url,this.props.protocol),attempts:1},this.open=this.open.bind(this),this.close=this.close.bind(this),this.sendMessage=this.sendMessage.bind(this),this.setupWebsocket=this.setupWebsocket.bind(this)}logging(e){!0===this.props.debug&&console.log(e)}generateInterval(e){return this.props.reconnectIntervalInMilliSeconds>0?this.props.reconnectIntervalInMilliSeconds:1e3*Math.min(30,Math.pow(2,e)-1)}setupWebsocket(){let e=this.state.ws;e.onopen=()=>{this.logging("Websocket connected"),"function"==typeof this.props.onOpen&&this.props.onOpen()},e.onerror=e=>{"function"==typeof this.props.onError&&this.props.onError(e)},e.onmessage=e=>{this.props.onMessage(e.data)},this.shouldReconnect=this.props.reconnect,e.onclose=e=>{if(this.logging(`Websocket disconnected,the reason: ${e.reason},the code: ${e.code}`),"function"==typeof this.props.onClose&&this.props.onClose(e.code,e.reason),this.shouldReconnect){let e=this.generateInterval(this.state.attempts);this.timeoutID=setTimeout(()=>{this.setState({attempts:this.state.attempts+1}),this.setState({ws:window.WebSocket?new window.WebSocket(this.props.url,this.props.protocol):new window.MozWebSocket(this.props.url,this.props.protocol)}),this.setupWebsocket()},e)}}}componentDidMount(){this.setupWebsocket()}componentWillUnmount(){this.shouldReconnect=!1,clearTimeout(this.timeoutID),this.state.ws.close()}sendMessage(e){this.state.ws.send(e)}open(){this.setupWebsocket()}close(){this.state.ws.close()}render(){return t().createElement("div",null)}}i.defaultProps={debug:!1,reconnect:!0},i.propTypes={url:r().string.isRequired,onMessage:r().func.isRequired,onOpen:r().func,onClose:r().func,onError:r().func,debug:r().bool,reconnect:r().bool,protocol:r().string,reconnectIntervalInMilliSeconds:r().number};const p=i;s.d(n,["default",0,p])})(),n})());
|
|
2
|
-
//# sourceMappingURL=index.map
|
package/build/index.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://Spinner/webpack/universalModuleDefinition","webpack://Spinner/./node_modules/prop-types/factoryWithThrowingShims.js","webpack://Spinner/./node_modules/prop-types/index.js","webpack://Spinner/./node_modules/prop-types/lib/ReactPropTypesSecret.js","webpack://Spinner/external umd {\"root\":\"React\",\"commonjs2\":\"react\",\"commonjs\":\"react\",\"amd\":\"react\"}","webpack://Spinner/webpack/bootstrap","webpack://Spinner/webpack/runtime/compat get default export","webpack://Spinner/webpack/runtime/define property getters","webpack://Spinner/webpack/runtime/hasOwnProperty shorthand","webpack://Spinner/webpack/runtime/make namespace object","webpack://Spinner/./index.jsx"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Spinner\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Spinner\"] = factory(root[\"React\"]);\n})(this, (__WEBPACK_EXTERNAL_MODULE__442__) => {\nreturn ","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n var ReactPropTypes = {\n array: shim,\n bigint: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n elementType: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim,\n\n checkPropTypes: emptyFunctionWithReset,\n resetWarningCache: emptyFunction\n };\n\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactIs = require('react-is');\n\n // By explicitly using `prop-types` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","module.exports = __WEBPACK_EXTERNAL_MODULE__442__;","// The module cache\nconst __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tconst cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tconst module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tconst getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter/value functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tif(Array.isArray(definition)) {\n\t\tvar i = 0;\n\t\twhile(i < definition.length) {\n\t\t\tvar key = definition[i++];\n\t\t\tvar binding = definition[i++];\n\t\t\tvar descriptor = binding === 0 ? { enumerable: true, value: definition[i++] } : { enumerable: true, get: binding };\n\t\t\tif(!__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, descriptor);\n\t\t}\n\t} else {\n\t\tfor(var key in definition) {\n\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t\t}\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop));","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import React from 'react';\nimport PropTypes from 'prop-types';\n\nclass Websocket extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n ws: window.WebSocket\n ? new window.WebSocket(this.props.url, this.props.protocol)\n : new window.MozWebSocket(this.props.url, this.props.protocol),\n attempts: 1\n };\n this.open = this.open.bind(this);\n this.close = this.close.bind(this);\n this.sendMessage = this.sendMessage.bind(this);\n this.setupWebsocket = this.setupWebsocket.bind(this);\n }\n\n logging(logline) {\n if (this.props.debug === true) {\n console.log(logline);\n }\n }\n\n generateInterval(k) {\n if (this.props.reconnectIntervalInMilliSeconds > 0) {\n return this.props.reconnectIntervalInMilliSeconds;\n }\n return Math.min(30, Math.pow(2, k) - 1) * 1000;\n }\n\n setupWebsocket() {\n let websocket = this.state.ws;\n\n websocket.onopen = () => {\n this.logging('Websocket connected');\n if (typeof this.props.onOpen === 'function') this.props.onOpen();\n };\n\n websocket.onerror = e => {\n if (typeof this.props.onError === 'function') this.props.onError(e);\n };\n\n websocket.onmessage = evt => {\n this.props.onMessage(evt.data);\n };\n\n this.shouldReconnect = this.props.reconnect;\n websocket.onclose = evt => {\n this.logging(\n `Websocket disconnected,the reason: ${evt.reason},the code: ${evt.code}`\n );\n if (typeof this.props.onClose === 'function')\n this.props.onClose(evt.code, evt.reason);\n if (this.shouldReconnect) {\n let time = this.generateInterval(this.state.attempts);\n this.timeoutID = setTimeout(() => {\n this.setState({ attempts: this.state.attempts + 1 });\n this.setState({\n ws: window.WebSocket\n ? new window.WebSocket(this.props.url, this.props.protocol)\n : new window.MozWebSocket(this.props.url, this.props.protocol)\n });\n this.setupWebsocket();\n }, time);\n }\n };\n }\n\n componentDidMount() {\n this.setupWebsocket();\n }\n\n componentWillUnmount() {\n this.shouldReconnect = false;\n clearTimeout(this.timeoutID);\n let websocket = this.state.ws;\n websocket.close();\n }\n\n sendMessage(message) {\n let websocket = this.state.ws;\n websocket.send(message);\n }\n\n open() {\n this.setupWebsocket();\n }\n\n close() {\n let websocket = this.state.ws;\n websocket.close();\n }\n\n render() {\n return <div></div>;\n }\n}\n\nWebsocket.defaultProps = {\n debug: false,\n reconnect: true\n};\n\nWebsocket.propTypes = {\n url: PropTypes.string.isRequired,\n onMessage: PropTypes.func.isRequired,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n onError: PropTypes.func,\n debug: PropTypes.bool,\n reconnect: PropTypes.bool,\n protocol: PropTypes.string,\n reconnectIntervalInMilliSeconds: PropTypes.number\n};\n\nexport default Websocket;\n"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE__442__","ReactPropTypesSecret","__webpack_require__","emptyFunction","emptyFunctionWithReset","resetWarningCache","shim","props","propName","componentName","location","propFullName","secret","err","Error","name","getShim","isRequired","ReactPropTypes","array","bigint","bool","func","number","object","string","symbol","any","arrayOf","element","elementType","instanceOf","node","objectOf","oneOf","oneOfType","shape","exact","checkPropTypes","PropTypes","__webpack_module_cache__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","Array","isArray","i","length","key","binding","descriptor","enumerable","value","get","o","Object","defineProperty","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","Websocket","react__WEBPACK_IMPORTED_MODULE_0___default","constructor","super","state","ws","window","WebSocket","url","protocol","MozWebSocket","attempts","open","bind","close","sendMessage","setupWebsocket","logging","logline","debug","console","log","generateInterval","k","reconnectIntervalInMilliSeconds","Math","min","pow","websocket","onopen","onOpen","onerror","e","onError","onmessage","evt","onMessage","data","shouldReconnect","reconnect","onclose","reason","code","onClose","time","timeoutID","setTimeout","setState","componentDidMount","componentWillUnmount","clearTimeout","message","send","render","createElement","defaultProps","propTypes","prop_types__WEBPACK_IMPORTED_MODULE_1___default","index"],"sourceRoot":""}
|
package/index.jsx
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
class Websocket extends React.Component {
|
|
5
|
-
constructor(props) {
|
|
6
|
-
super(props);
|
|
7
|
-
this.state = {
|
|
8
|
-
ws: window.WebSocket
|
|
9
|
-
? new window.WebSocket(this.props.url, this.props.protocol)
|
|
10
|
-
: new window.MozWebSocket(this.props.url, this.props.protocol),
|
|
11
|
-
attempts: 1
|
|
12
|
-
};
|
|
13
|
-
this.open = this.open.bind(this);
|
|
14
|
-
this.close = this.close.bind(this);
|
|
15
|
-
this.sendMessage = this.sendMessage.bind(this);
|
|
16
|
-
this.setupWebsocket = this.setupWebsocket.bind(this);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
logging(logline) {
|
|
20
|
-
if (this.props.debug === true) {
|
|
21
|
-
console.log(logline);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
generateInterval(k) {
|
|
26
|
-
if (this.props.reconnectIntervalInMilliSeconds > 0) {
|
|
27
|
-
return this.props.reconnectIntervalInMilliSeconds;
|
|
28
|
-
}
|
|
29
|
-
return Math.min(30, Math.pow(2, k) - 1) * 1000;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
setupWebsocket() {
|
|
33
|
-
let websocket = this.state.ws;
|
|
34
|
-
|
|
35
|
-
websocket.onopen = () => {
|
|
36
|
-
this.logging('Websocket connected');
|
|
37
|
-
if (typeof this.props.onOpen === 'function') this.props.onOpen();
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
websocket.onerror = e => {
|
|
41
|
-
if (typeof this.props.onError === 'function') this.props.onError(e);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
websocket.onmessage = evt => {
|
|
45
|
-
this.props.onMessage(evt.data);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
this.shouldReconnect = this.props.reconnect;
|
|
49
|
-
websocket.onclose = evt => {
|
|
50
|
-
this.logging(
|
|
51
|
-
`Websocket disconnected,the reason: ${evt.reason},the code: ${evt.code}`
|
|
52
|
-
);
|
|
53
|
-
if (typeof this.props.onClose === 'function')
|
|
54
|
-
this.props.onClose(evt.code, evt.reason);
|
|
55
|
-
if (this.shouldReconnect) {
|
|
56
|
-
let time = this.generateInterval(this.state.attempts);
|
|
57
|
-
this.timeoutID = setTimeout(() => {
|
|
58
|
-
this.setState({ attempts: this.state.attempts + 1 });
|
|
59
|
-
this.setState({
|
|
60
|
-
ws: window.WebSocket
|
|
61
|
-
? new window.WebSocket(this.props.url, this.props.protocol)
|
|
62
|
-
: new window.MozWebSocket(this.props.url, this.props.protocol)
|
|
63
|
-
});
|
|
64
|
-
this.setupWebsocket();
|
|
65
|
-
}, time);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
componentDidMount() {
|
|
71
|
-
this.setupWebsocket();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
componentWillUnmount() {
|
|
75
|
-
this.shouldReconnect = false;
|
|
76
|
-
clearTimeout(this.timeoutID);
|
|
77
|
-
let websocket = this.state.ws;
|
|
78
|
-
websocket.close();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
sendMessage(message) {
|
|
82
|
-
let websocket = this.state.ws;
|
|
83
|
-
websocket.send(message);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
open() {
|
|
87
|
-
this.setupWebsocket();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
close() {
|
|
91
|
-
let websocket = this.state.ws;
|
|
92
|
-
websocket.close();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
render() {
|
|
96
|
-
return <div></div>;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
Websocket.defaultProps = {
|
|
101
|
-
debug: false,
|
|
102
|
-
reconnect: true
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
Websocket.propTypes = {
|
|
106
|
-
url: PropTypes.string.isRequired,
|
|
107
|
-
onMessage: PropTypes.func.isRequired,
|
|
108
|
-
onOpen: PropTypes.func,
|
|
109
|
-
onClose: PropTypes.func,
|
|
110
|
-
onError: PropTypes.func,
|
|
111
|
-
debug: PropTypes.bool,
|
|
112
|
-
reconnect: PropTypes.bool,
|
|
113
|
-
protocol: PropTypes.string,
|
|
114
|
-
reconnectIntervalInMilliSeconds: PropTypes.number
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export default Websocket;
|
package/webpack.config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
var path = require('path');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
mode: 'development',
|
|
5
|
-
devtool: 'eval-source-map',
|
|
6
|
-
entry: './example/index.jsx',
|
|
7
|
-
output: {
|
|
8
|
-
path: path.join(__dirname, 'example', 'static'),
|
|
9
|
-
filename: 'bundle.js',
|
|
10
|
-
},
|
|
11
|
-
resolve: {
|
|
12
|
-
extensions: ['.js', '.jsx'],
|
|
13
|
-
},
|
|
14
|
-
module: {
|
|
15
|
-
rules: [{
|
|
16
|
-
test: /\.jsx?$/,
|
|
17
|
-
exclude: /build|node_modules/,
|
|
18
|
-
use: 'babel-loader',
|
|
19
|
-
}],
|
|
20
|
-
},
|
|
21
|
-
};
|
package/webpack.prod.config.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
var path = require('path');
|
|
2
|
-
|
|
3
|
-
var config = {
|
|
4
|
-
mode: 'production',
|
|
5
|
-
devtool: 'source-map',
|
|
6
|
-
entry: {
|
|
7
|
-
index: './index.jsx',
|
|
8
|
-
},
|
|
9
|
-
output: {
|
|
10
|
-
path: path.join(__dirname, 'build'),
|
|
11
|
-
publicPath: './build',
|
|
12
|
-
filename: 'index.js',
|
|
13
|
-
sourceMapFilename: 'index.map',
|
|
14
|
-
library: {
|
|
15
|
-
name: 'Spinner',
|
|
16
|
-
type: 'umd',
|
|
17
|
-
},
|
|
18
|
-
globalObject: 'this',
|
|
19
|
-
},
|
|
20
|
-
module: {
|
|
21
|
-
rules: [{
|
|
22
|
-
test: /\.jsx?$/,
|
|
23
|
-
exclude: /node_modules/,
|
|
24
|
-
use: 'babel-loader',
|
|
25
|
-
}],
|
|
26
|
-
},
|
|
27
|
-
resolve: {
|
|
28
|
-
extensions: ['.js', '.jsx'],
|
|
29
|
-
},
|
|
30
|
-
externals: {
|
|
31
|
-
'react': {
|
|
32
|
-
root: 'React',
|
|
33
|
-
commonjs2: 'react',
|
|
34
|
-
commonjs: 'react',
|
|
35
|
-
amd: 'react',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
module.exports = config;
|