@bunworks/inngest-realtime 0.1.0 → 0.1.5

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 (101) hide show
  1. package/CHANGELOG.md +6 -6
  2. package/README.md +1 -1
  3. package/_virtual/_rolldown/runtime.cjs +29 -0
  4. package/api.cjs +45 -0
  5. package/api.cjs.map +1 -0
  6. package/api.mjs +44 -0
  7. package/api.mjs.map +1 -0
  8. package/channel.cjs +67 -0
  9. package/channel.cjs.map +1 -0
  10. package/channel.d.cts +19 -0
  11. package/channel.d.cts.map +1 -0
  12. package/channel.d.mts +19 -0
  13. package/channel.d.mts.map +1 -0
  14. package/channel.mjs +66 -0
  15. package/channel.mjs.map +1 -0
  16. package/env.cjs +72 -0
  17. package/env.cjs.map +1 -0
  18. package/env.mjs +71 -0
  19. package/env.mjs.map +1 -0
  20. package/hooks.cjs +147 -0
  21. package/hooks.cjs.map +1 -0
  22. package/hooks.d.cts +70 -0
  23. package/hooks.d.cts.map +1 -0
  24. package/hooks.d.mts +70 -0
  25. package/hooks.d.mts.map +1 -0
  26. package/hooks.mjs +144 -0
  27. package/hooks.mjs.map +1 -0
  28. package/index.cjs +19 -0
  29. package/index.d.cts +5 -0
  30. package/index.d.mts +6 -0
  31. package/index.mjs +7 -0
  32. package/middleware.cjs +41 -0
  33. package/middleware.cjs.map +1 -0
  34. package/middleware.d.cts +29 -0
  35. package/middleware.d.cts.map +1 -0
  36. package/middleware.d.mts +29 -0
  37. package/middleware.d.mts.map +1 -0
  38. package/middleware.mjs +34 -0
  39. package/middleware.mjs.map +1 -0
  40. package/package.json +6 -5
  41. package/subscribe/StreamFanout.cjs +47 -0
  42. package/subscribe/StreamFanout.cjs.map +1 -0
  43. package/subscribe/StreamFanout.mjs +46 -0
  44. package/subscribe/StreamFanout.mjs.map +1 -0
  45. package/subscribe/TokenSubscription.cjs +438 -0
  46. package/subscribe/TokenSubscription.cjs.map +1 -0
  47. package/subscribe/TokenSubscription.mjs +436 -0
  48. package/subscribe/TokenSubscription.mjs.map +1 -0
  49. package/subscribe/helpers.cjs +41 -0
  50. package/subscribe/helpers.cjs.map +1 -0
  51. package/subscribe/helpers.d.cts +64 -0
  52. package/subscribe/helpers.d.cts.map +1 -0
  53. package/subscribe/helpers.d.mts +64 -0
  54. package/subscribe/helpers.d.mts.map +1 -0
  55. package/subscribe/helpers.mjs +40 -0
  56. package/subscribe/helpers.mjs.map +1 -0
  57. package/subscribe/index.cjs +1 -0
  58. package/subscribe/index.d.mts +1 -0
  59. package/subscribe/index.mjs +3 -0
  60. package/topic.cjs +30 -0
  61. package/topic.cjs.map +1 -0
  62. package/topic.d.cts +19 -0
  63. package/topic.d.cts.map +1 -0
  64. package/topic.d.mts +19 -0
  65. package/topic.d.mts.map +1 -0
  66. package/topic.mjs +28 -0
  67. package/topic.mjs.map +1 -0
  68. package/types.cjs +45 -0
  69. package/types.cjs.map +1 -0
  70. package/types.d.cts +241 -0
  71. package/types.d.cts.map +1 -0
  72. package/types.d.mts +241 -0
  73. package/types.d.mts.map +1 -0
  74. package/types.mjs +39 -0
  75. package/types.mjs.map +1 -0
  76. package/util.cjs +72 -0
  77. package/util.cjs.map +1 -0
  78. package/util.mjs +69 -0
  79. package/util.mjs.map +1 -0
  80. package/CLAUDE.md +0 -69
  81. package/bun.lock +0 -527
  82. package/eslint.config.mjs +0 -19
  83. package/src/api.ts +0 -83
  84. package/src/channel.ts +0 -122
  85. package/src/env.d.ts +0 -15
  86. package/src/env.ts +0 -152
  87. package/src/hooks.ts +0 -256
  88. package/src/index.test.ts +0 -840
  89. package/src/index.ts +0 -4
  90. package/src/middleware.ts +0 -68
  91. package/src/subscribe/StreamFanout.ts +0 -82
  92. package/src/subscribe/TokenSubscription.ts +0 -524
  93. package/src/subscribe/helpers.ts +0 -153
  94. package/src/subscribe/index.ts +0 -1
  95. package/src/topic.ts +0 -51
  96. package/src/types.ts +0 -499
  97. package/src/util.ts +0 -104
  98. package/tsconfig.build.json +0 -7
  99. package/tsconfig.json +0 -114
  100. package/tsdown.config.ts +0 -18
  101. package/vitest.config.ts +0 -22
package/util.cjs ADDED
@@ -0,0 +1,72 @@
1
+
2
+ //#region src/util.ts
3
+ /**
4
+ * Creates and returns Promise that can be resolved or rejected with the
5
+ * returned `resolve` and `reject` functions.
6
+ *
7
+ * Resolving or rejecting the function will return a new set of Promise control
8
+ * functions. These can be ignored if the original Promise is all that's needed.
9
+ */
10
+ const createDeferredPromise = () => {
11
+ let resolve;
12
+ let reject;
13
+ return {
14
+ promise: new Promise((_resolve, _reject) => {
15
+ resolve = (value) => {
16
+ _resolve(value);
17
+ return createDeferredPromise();
18
+ };
19
+ reject = (reason) => {
20
+ _reject(reason);
21
+ return createDeferredPromise();
22
+ };
23
+ }),
24
+ resolve,
25
+ reject
26
+ };
27
+ };
28
+ /**
29
+ * Send an HTTP request with the given signing key. If the response is a 401 or
30
+ * 403, then try again with the fallback signing key
31
+ */
32
+ async function fetchWithAuthFallback({ authToken, authTokenFallback, fetch, options, url }) {
33
+ let res = await fetch(url, {
34
+ ...options,
35
+ headers: {
36
+ ...options?.headers,
37
+ ...authToken ? { Authorization: `Bearer ${authToken}` } : {}
38
+ }
39
+ });
40
+ if ([401, 403].includes(res.status) && authTokenFallback) res = await fetch(url, {
41
+ ...options,
42
+ headers: {
43
+ ...options?.headers,
44
+ Authorization: `Bearer ${authTokenFallback}`
45
+ }
46
+ });
47
+ return res;
48
+ }
49
+ /**
50
+ * Given an unknown value, try to parse it as a `boolean`. Useful for parsing
51
+ * environment variables that could be a selection of different values such as
52
+ * `"true"`, `"1"`.
53
+ *
54
+ * If the value could not be confidently parsed as a `boolean` or was seen to be
55
+ * `undefined`, this function returns `undefined`.
56
+ */
57
+ const parseAsBoolean = (value) => {
58
+ if (typeof value === "boolean") return value;
59
+ if (typeof value === "number") return Boolean(value);
60
+ if (typeof value === "string") {
61
+ const trimmed = value.trim().toLowerCase();
62
+ if (trimmed === "undefined") return;
63
+ if (["true", "1"].includes(trimmed)) return true;
64
+ return false;
65
+ }
66
+ };
67
+
68
+ //#endregion
69
+ exports.createDeferredPromise = createDeferredPromise;
70
+ exports.fetchWithAuthFallback = fetchWithAuthFallback;
71
+ exports.parseAsBoolean = parseAsBoolean;
72
+ //# sourceMappingURL=util.cjs.map
package/util.cjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.cjs","names":[],"sources":["../src/util.ts"],"sourcesContent":["type DeferredPromiseReturn<T> = {\r\n promise: Promise<T>;\r\n resolve: (value: T) => DeferredPromiseReturn<T>;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n reject: (reason: any) => DeferredPromiseReturn<T>;\r\n};\r\n\r\n/**\r\n * Creates and returns Promise that can be resolved or rejected with the\r\n * returned `resolve` and `reject` functions.\r\n *\r\n * Resolving or rejecting the function will return a new set of Promise control\r\n * functions. These can be ignored if the original Promise is all that's needed.\r\n */\r\nexport const createDeferredPromise = <T>(): DeferredPromiseReturn<T> => {\r\n let resolve: DeferredPromiseReturn<T>[\"resolve\"];\r\n let reject: DeferredPromiseReturn<T>[\"reject\"];\r\n\r\n const promise = new Promise<T>((_resolve, _reject) => {\r\n resolve = (value: T) => {\r\n _resolve(value);\r\n return createDeferredPromise<T>();\r\n };\r\n\r\n reject = (reason) => {\r\n _reject(reason);\r\n return createDeferredPromise<T>();\r\n };\r\n });\r\n\r\n return { promise, resolve: resolve!, reject: reject! };\r\n};\r\n\r\n/**\r\n * Send an HTTP request with the given signing key. If the response is a 401 or\r\n * 403, then try again with the fallback signing key\r\n */\r\nexport async function fetchWithAuthFallback<TFetch extends typeof fetch>({\r\n authToken,\r\n authTokenFallback,\r\n fetch,\r\n options,\r\n url,\r\n}: {\r\n authToken: string | undefined;\r\n authTokenFallback: string | undefined;\r\n fetch: TFetch;\r\n options?: Parameters<TFetch>[1];\r\n url: URL | string;\r\n}): Promise<Response> {\r\n let res = await fetch(url, {\r\n ...options,\r\n headers: {\r\n ...options?.headers,\r\n ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),\r\n },\r\n });\r\n\r\n if ([401, 403].includes(res.status) && authTokenFallback) {\r\n res = await fetch(url, {\r\n ...options,\r\n headers: {\r\n ...options?.headers,\r\n Authorization: `Bearer ${authTokenFallback}`,\r\n },\r\n });\r\n }\r\n\r\n return res;\r\n}\r\n\r\n/**\r\n * Given an unknown value, try to parse it as a `boolean`. Useful for parsing\r\n * environment variables that could be a selection of different values such as\r\n * `\"true\"`, `\"1\"`.\r\n *\r\n * If the value could not be confidently parsed as a `boolean` or was seen to be\r\n * `undefined`, this function returns `undefined`.\r\n */\r\nexport const parseAsBoolean = (value: unknown): boolean | undefined => {\r\n if (typeof value === \"boolean\") {\r\n return value;\r\n }\r\n\r\n if (typeof value === \"number\") {\r\n return Boolean(value);\r\n }\r\n\r\n if (typeof value === \"string\") {\r\n const trimmed = value.trim().toLowerCase();\r\n\r\n if (trimmed === \"undefined\") {\r\n return undefined;\r\n }\r\n\r\n if ([\"true\", \"1\"].includes(trimmed)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return undefined;\r\n};\r\n"],"mappings":";;;;;;;;;AAcA,MAAa,8BAA2D;CACtE,IAAI;CACJ,IAAI;AAcJ,QAAO;EAAE,SAZO,IAAI,SAAY,UAAU,YAAY;AACpD,cAAW,UAAa;AACtB,aAAS,MAAM;AACf,WAAO,uBAA0B;;AAGnC,aAAU,WAAW;AACnB,YAAQ,OAAO;AACf,WAAO,uBAA0B;;IAEnC;EAEyB;EAAkB;EAAS;;;;;;AAOxD,eAAsB,sBAAmD,EACvE,WACA,mBACA,OACA,SACA,OAOoB;CACpB,IAAI,MAAM,MAAM,MAAM,KAAK;EACzB,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,GAAI,YAAY,EAAE,eAAe,UAAU,aAAa,GAAG,EAAE;GAC9D;EACF,CAAC;AAEF,KAAI,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,kBACrC,OAAM,MAAM,MAAM,KAAK;EACrB,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,eAAe,UAAU;GAC1B;EACF,CAAC;AAGJ,QAAO;;;;;;;;;;AAWT,MAAa,kBAAkB,UAAwC;AACrE,KAAI,OAAO,UAAU,UACnB,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO,QAAQ,MAAM;AAGvB,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,UAAU,MAAM,MAAM,CAAC,aAAa;AAE1C,MAAI,YAAY,YACd;AAGF,MAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,QAAQ,CACjC,QAAO;AAGT,SAAO"}
package/util.mjs ADDED
@@ -0,0 +1,69 @@
1
+ //#region src/util.ts
2
+ /**
3
+ * Creates and returns Promise that can be resolved or rejected with the
4
+ * returned `resolve` and `reject` functions.
5
+ *
6
+ * Resolving or rejecting the function will return a new set of Promise control
7
+ * functions. These can be ignored if the original Promise is all that's needed.
8
+ */
9
+ const createDeferredPromise = () => {
10
+ let resolve;
11
+ let reject;
12
+ return {
13
+ promise: new Promise((_resolve, _reject) => {
14
+ resolve = (value) => {
15
+ _resolve(value);
16
+ return createDeferredPromise();
17
+ };
18
+ reject = (reason) => {
19
+ _reject(reason);
20
+ return createDeferredPromise();
21
+ };
22
+ }),
23
+ resolve,
24
+ reject
25
+ };
26
+ };
27
+ /**
28
+ * Send an HTTP request with the given signing key. If the response is a 401 or
29
+ * 403, then try again with the fallback signing key
30
+ */
31
+ async function fetchWithAuthFallback({ authToken, authTokenFallback, fetch, options, url }) {
32
+ let res = await fetch(url, {
33
+ ...options,
34
+ headers: {
35
+ ...options?.headers,
36
+ ...authToken ? { Authorization: `Bearer ${authToken}` } : {}
37
+ }
38
+ });
39
+ if ([401, 403].includes(res.status) && authTokenFallback) res = await fetch(url, {
40
+ ...options,
41
+ headers: {
42
+ ...options?.headers,
43
+ Authorization: `Bearer ${authTokenFallback}`
44
+ }
45
+ });
46
+ return res;
47
+ }
48
+ /**
49
+ * Given an unknown value, try to parse it as a `boolean`. Useful for parsing
50
+ * environment variables that could be a selection of different values such as
51
+ * `"true"`, `"1"`.
52
+ *
53
+ * If the value could not be confidently parsed as a `boolean` or was seen to be
54
+ * `undefined`, this function returns `undefined`.
55
+ */
56
+ const parseAsBoolean = (value) => {
57
+ if (typeof value === "boolean") return value;
58
+ if (typeof value === "number") return Boolean(value);
59
+ if (typeof value === "string") {
60
+ const trimmed = value.trim().toLowerCase();
61
+ if (trimmed === "undefined") return;
62
+ if (["true", "1"].includes(trimmed)) return true;
63
+ return false;
64
+ }
65
+ };
66
+
67
+ //#endregion
68
+ export { createDeferredPromise, fetchWithAuthFallback, parseAsBoolean };
69
+ //# sourceMappingURL=util.mjs.map
package/util.mjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.mjs","names":[],"sources":["../src/util.ts"],"sourcesContent":["type DeferredPromiseReturn<T> = {\r\n promise: Promise<T>;\r\n resolve: (value: T) => DeferredPromiseReturn<T>;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n reject: (reason: any) => DeferredPromiseReturn<T>;\r\n};\r\n\r\n/**\r\n * Creates and returns Promise that can be resolved or rejected with the\r\n * returned `resolve` and `reject` functions.\r\n *\r\n * Resolving or rejecting the function will return a new set of Promise control\r\n * functions. These can be ignored if the original Promise is all that's needed.\r\n */\r\nexport const createDeferredPromise = <T>(): DeferredPromiseReturn<T> => {\r\n let resolve: DeferredPromiseReturn<T>[\"resolve\"];\r\n let reject: DeferredPromiseReturn<T>[\"reject\"];\r\n\r\n const promise = new Promise<T>((_resolve, _reject) => {\r\n resolve = (value: T) => {\r\n _resolve(value);\r\n return createDeferredPromise<T>();\r\n };\r\n\r\n reject = (reason) => {\r\n _reject(reason);\r\n return createDeferredPromise<T>();\r\n };\r\n });\r\n\r\n return { promise, resolve: resolve!, reject: reject! };\r\n};\r\n\r\n/**\r\n * Send an HTTP request with the given signing key. If the response is a 401 or\r\n * 403, then try again with the fallback signing key\r\n */\r\nexport async function fetchWithAuthFallback<TFetch extends typeof fetch>({\r\n authToken,\r\n authTokenFallback,\r\n fetch,\r\n options,\r\n url,\r\n}: {\r\n authToken: string | undefined;\r\n authTokenFallback: string | undefined;\r\n fetch: TFetch;\r\n options?: Parameters<TFetch>[1];\r\n url: URL | string;\r\n}): Promise<Response> {\r\n let res = await fetch(url, {\r\n ...options,\r\n headers: {\r\n ...options?.headers,\r\n ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),\r\n },\r\n });\r\n\r\n if ([401, 403].includes(res.status) && authTokenFallback) {\r\n res = await fetch(url, {\r\n ...options,\r\n headers: {\r\n ...options?.headers,\r\n Authorization: `Bearer ${authTokenFallback}`,\r\n },\r\n });\r\n }\r\n\r\n return res;\r\n}\r\n\r\n/**\r\n * Given an unknown value, try to parse it as a `boolean`. Useful for parsing\r\n * environment variables that could be a selection of different values such as\r\n * `\"true\"`, `\"1\"`.\r\n *\r\n * If the value could not be confidently parsed as a `boolean` or was seen to be\r\n * `undefined`, this function returns `undefined`.\r\n */\r\nexport const parseAsBoolean = (value: unknown): boolean | undefined => {\r\n if (typeof value === \"boolean\") {\r\n return value;\r\n }\r\n\r\n if (typeof value === \"number\") {\r\n return Boolean(value);\r\n }\r\n\r\n if (typeof value === \"string\") {\r\n const trimmed = value.trim().toLowerCase();\r\n\r\n if (trimmed === \"undefined\") {\r\n return undefined;\r\n }\r\n\r\n if ([\"true\", \"1\"].includes(trimmed)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return undefined;\r\n};\r\n"],"mappings":";;;;;;;;AAcA,MAAa,8BAA2D;CACtE,IAAI;CACJ,IAAI;AAcJ,QAAO;EAAE,SAZO,IAAI,SAAY,UAAU,YAAY;AACpD,cAAW,UAAa;AACtB,aAAS,MAAM;AACf,WAAO,uBAA0B;;AAGnC,aAAU,WAAW;AACnB,YAAQ,OAAO;AACf,WAAO,uBAA0B;;IAEnC;EAEyB;EAAkB;EAAS;;;;;;AAOxD,eAAsB,sBAAmD,EACvE,WACA,mBACA,OACA,SACA,OAOoB;CACpB,IAAI,MAAM,MAAM,MAAM,KAAK;EACzB,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,GAAI,YAAY,EAAE,eAAe,UAAU,aAAa,GAAG,EAAE;GAC9D;EACF,CAAC;AAEF,KAAI,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,kBACrC,OAAM,MAAM,MAAM,KAAK;EACrB,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,eAAe,UAAU;GAC1B;EACF,CAAC;AAGJ,QAAO;;;;;;;;;;AAWT,MAAa,kBAAkB,UAAwC;AACrE,KAAI,OAAO,UAAU,UACnB,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO,QAAQ,MAAM;AAGvB,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,UAAU,MAAM,MAAM,CAAC,aAAa;AAE1C,MAAI,YAAY,YACd;AAGF,MAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,QAAQ,CACjC,QAAO;AAGT,SAAO"}
package/CLAUDE.md DELETED
@@ -1,69 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Package Overview
6
-
7
- This is the `@inngest/realtime` package - a React-focused library that provides real-time capabilities for Inngest applications. It enables real-time subscriptions, channel management, and React hooks for building interactive applications with live data updates.
8
-
9
- ## Development Workflow
10
-
11
- ### Setup
12
- ```bash
13
- # From the realtime package directory
14
- cd packages/realtime/
15
- pnpm install
16
- ```
17
-
18
- ### Common Commands
19
-
20
- ```bash
21
- pnpm test # Run Jest tests
22
- pnpm build # Build TypeScript to dist/
23
- pnpm pack # Create inngest-realtime.tgz for local testing
24
- ```
25
-
26
- ### Testing Strategy
27
-
28
- - **Unit tests**: Jest (`pnpm test`)
29
- - **React testing**: Tests React hooks and components
30
- - Uses `ts-jest` for TypeScript support
31
-
32
- ## Architecture
33
-
34
- ### Key Concepts
35
- - **Real-time Subscriptions**: Live data streaming capabilities
36
- - **Channel Management**: Topic-based message routing
37
- - **React Integration**: Custom hooks for React applications
38
- - **Token-based Authentication**: Secure subscription management
39
-
40
- ### Package Structure
41
- - `src/index.ts` - Main exports and core functionality
42
- - `src/hooks.ts` - React hooks for real-time features
43
- - `src/channel.ts` - Channel management logic
44
- - `src/topic.ts` - Topic-based messaging
45
- - `src/api.ts` - API integration layer
46
- - `src/middleware.ts` - Inngest middleware integration
47
- - `src/subscribe/` - Subscription management utilities
48
-
49
- ### Exports
50
- The package provides two main export paths:
51
- - `@inngest/realtime` - Core real-time functionality
52
- - `@inngest/realtime/hooks` - React hooks specifically
53
-
54
- ## React Integration
55
-
56
- This package is designed specifically for React applications (requires React >=18.0.0):
57
- - Provides React hooks for real-time subscriptions
58
- - Manages WebSocket connections and state
59
- - Integrates with React's concurrent features
60
-
61
- ## Dependencies
62
-
63
- - **Peer Dependencies**: React >=18.0.0 (required)
64
- - **Core Dependencies**: inngest, zod for validation, debug for logging
65
- - **Schema Validation**: Supports both Zod and Valibot for schema validation
66
-
67
- ## Integration with Inngest
68
-
69
- Works as middleware and extension to the main Inngest package, providing real-time capabilities that complement Inngest's event-driven architecture.