@shopify/ui-extensions-server-kit 5.4.0 → 5.5.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.
Files changed (227) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +3 -3
  3. package/dist/ExtensionServerClient/ExtensionServerClient.d.ts +3 -5
  4. package/dist/ExtensionServerClient/server-types.d.ts +31 -7
  5. package/dist/_virtual/jsx-runtime.cjs.js +1 -0
  6. package/dist/_virtual/jsx-runtime.cjs2.js +1 -0
  7. package/dist/_virtual/jsx-runtime.es.js +5 -0
  8. package/dist/_virtual/jsx-runtime.es2.js +4 -0
  9. package/dist/_virtual/react-jsx-runtime.development.cjs.js +1 -0
  10. package/dist/_virtual/react-jsx-runtime.development.es.js +4 -0
  11. package/dist/_virtual/react-jsx-runtime.production.min.cjs.js +1 -0
  12. package/dist/_virtual/react-jsx-runtime.production.min.es.js +4 -0
  13. package/dist/i18n.d.ts +2 -8
  14. package/dist/index.cjs.js +1 -1
  15. package/dist/index.cjs2.js +1 -1
  16. package/dist/index.es.js +18 -18
  17. package/dist/index.es2.js +3 -3
  18. package/dist/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.development.cjs.js +22 -0
  19. package/dist/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.development.es.js +604 -0
  20. package/dist/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.cjs.js +9 -0
  21. package/dist/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.es.js +28 -0
  22. package/dist/node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.cjs.js +1 -0
  23. package/dist/node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.es.js +10 -0
  24. package/dist/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.cjs.js +1 -0
  25. package/dist/{ExtensionServerClient → packages/ui-extensions-server-kit/src/ExtensionServerClient}/ExtensionServerClient.es.js +21 -18
  26. package/dist/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.cjs.js +1 -0
  27. package/dist/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.es.js +30 -0
  28. package/dist/{context → packages/ui-extensions-server-kit/src/context}/constants.cjs.js +1 -1
  29. package/dist/packages/ui-extensions-server-kit/src/hooks/useExtensionServerContext.cjs.js +1 -0
  30. package/dist/{hooks → packages/ui-extensions-server-kit/src/hooks}/useExtensionServerContext.es.js +3 -2
  31. package/dist/packages/ui-extensions-server-kit/src/testing/MockExtensionServerProvider.cjs.js +1 -0
  32. package/dist/packages/ui-extensions-server-kit/src/testing/MockExtensionServerProvider.es.js +25 -0
  33. package/dist/packages/ui-extensions-server-kit/src/utilities/isUIExtension.cjs.js +1 -0
  34. package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/isUIExtension.es.js +3 -2
  35. package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/isValidSurface.cjs.js +1 -1
  36. package/dist/packages/ui-extensions-server-kit/src/utilities/isValidSurface.es.js +7 -0
  37. package/dist/types.d.ts +21 -8
  38. package/dist/utilities/isUIExtension.d.ts +1 -1
  39. package/dist/utilities/isValidSurface.d.ts +1 -1
  40. package/dist/utilities/set.d.ts +1 -1
  41. package/node_modules/{@shopify/react-testing/LICENSE.md → @testing-library/react/LICENSE} +2 -3
  42. package/node_modules/@testing-library/react/README.md +692 -0
  43. package/node_modules/@testing-library/react/dist/@testing-library/react.cjs.js +537 -0
  44. package/node_modules/@testing-library/react/dist/@testing-library/react.esm.js +497 -0
  45. package/node_modules/@testing-library/react/dist/@testing-library/react.pure.cjs.js +501 -0
  46. package/node_modules/@testing-library/react/dist/@testing-library/react.pure.esm.js +461 -0
  47. package/node_modules/@testing-library/react/dist/@testing-library/react.pure.umd.js +502 -0
  48. package/node_modules/@testing-library/react/dist/@testing-library/react.pure.umd.js.map +1 -0
  49. package/node_modules/@testing-library/react/dist/@testing-library/react.pure.umd.min.js +2 -0
  50. package/node_modules/@testing-library/react/dist/@testing-library/react.pure.umd.min.js.map +1 -0
  51. package/node_modules/@testing-library/react/dist/@testing-library/react.umd.js +538 -0
  52. package/node_modules/@testing-library/react/dist/@testing-library/react.umd.js.map +1 -0
  53. package/node_modules/@testing-library/react/dist/@testing-library/react.umd.min.js +2 -0
  54. package/node_modules/@testing-library/react/dist/@testing-library/react.umd.min.js.map +1 -0
  55. package/node_modules/@testing-library/react/dist/act-compat.js +80 -0
  56. package/node_modules/@testing-library/react/dist/config.js +33 -0
  57. package/node_modules/@testing-library/react/dist/fire-event.js +70 -0
  58. package/node_modules/@testing-library/react/dist/index.js +52 -0
  59. package/node_modules/@testing-library/react/dist/pure.js +356 -0
  60. package/node_modules/@testing-library/react/dont-cleanup-after-each.js +1 -0
  61. package/node_modules/@testing-library/react/package.json +116 -0
  62. package/node_modules/@testing-library/react/pure.d.ts +1 -0
  63. package/node_modules/@testing-library/react/pure.js +2 -0
  64. package/node_modules/@testing-library/react/types/index.d.ts +287 -0
  65. package/node_modules/@testing-library/react/types/pure.d.ts +1 -0
  66. package/node_modules/@vitejs/plugin-react/README.md +159 -0
  67. package/node_modules/@vitejs/plugin-react/dist/index.d.ts +75 -0
  68. package/node_modules/@vitejs/plugin-react/dist/index.js +401 -0
  69. package/node_modules/@vitejs/plugin-react/dist/refresh-runtime.js +663 -0
  70. package/node_modules/@vitejs/plugin-react/package.json +77 -0
  71. package/node_modules/@vitejs/plugin-react/types/preamble.d.ts +1 -0
  72. package/package.json +9 -10
  73. package/project.json +3 -21
  74. package/src/ExtensionServerClient/ExtensionServerClient.test.ts +6 -5
  75. package/src/ExtensionServerClient/ExtensionServerClient.ts +27 -19
  76. package/src/ExtensionServerClient/server-types.ts +17 -7
  77. package/src/ExtensionServerClient/types.ts +0 -2
  78. package/src/context/ExtensionServerProvider.test.tsx +55 -73
  79. package/src/context/ExtensionServerProvider.tsx +1 -0
  80. package/src/i18n.ts +2 -5
  81. package/src/state/reducers/extensionServerReducer.test.ts +16 -11
  82. package/src/types.ts +23 -6
  83. package/src/utilities/assetToString.ts +0 -1
  84. package/src/utilities/isUIExtension.ts +5 -4
  85. package/src/utilities/isValidSurface.ts +2 -3
  86. package/src/utilities/replaceUpdated.ts +0 -2
  87. package/src/utilities/set.ts +10 -5
  88. package/tests/setup.ts +1 -4
  89. package/vite.config.mts +57 -0
  90. package/dist/ExtensionServerClient/ExtensionServerClient.cjs.js +0 -1
  91. package/dist/context/ExtensionServerProvider.cjs.js +0 -1
  92. package/dist/context/ExtensionServerProvider.es.js +0 -29
  93. package/dist/hooks/useExtensionServerContext.cjs.js +0 -1
  94. package/dist/testing/MockExtensionServerProvider.cjs.js +0 -1
  95. package/dist/testing/MockExtensionServerProvider.es.js +0 -24
  96. package/dist/utilities/isUIExtension.cjs.js +0 -1
  97. package/dist/utilities/isValidSurface.es.js +0 -7
  98. package/node_modules/@shopify/react-testing/README.md +0 -711
  99. package/node_modules/@shopify/react-testing/build/cjs/TestWrapper.js +0 -52
  100. package/node_modules/@shopify/react-testing/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -47
  101. package/node_modules/@shopify/react-testing/build/cjs/compat.js +0 -14
  102. package/node_modules/@shopify/react-testing/build/cjs/destroy.js +0 -13
  103. package/node_modules/@shopify/react-testing/build/cjs/element.js +0 -225
  104. package/node_modules/@shopify/react-testing/build/cjs/index.js +0 -21
  105. package/node_modules/@shopify/react-testing/build/cjs/matchers/components.js +0 -46
  106. package/node_modules/@shopify/react-testing/build/cjs/matchers/context.js +0 -25
  107. package/node_modules/@shopify/react-testing/build/cjs/matchers/index.js +0 -16
  108. package/node_modules/@shopify/react-testing/build/cjs/matchers/props.js +0 -38
  109. package/node_modules/@shopify/react-testing/build/cjs/matchers/strings.js +0 -42
  110. package/node_modules/@shopify/react-testing/build/cjs/matchers/utilities.js +0 -110
  111. package/node_modules/@shopify/react-testing/build/cjs/mount.js +0 -76
  112. package/node_modules/@shopify/react-testing/build/cjs/root.js +0 -284
  113. package/node_modules/@shopify/react-testing/build/cjs/toReactString.js +0 -86
  114. package/node_modules/@shopify/react-testing/build/cjs/types.js +0 -28
  115. package/node_modules/@shopify/react-testing/build/esm/TestWrapper.mjs +0 -44
  116. package/node_modules/@shopify/react-testing/build/esm/_virtual/_rollupPluginBabelHelpers.mjs +0 -42
  117. package/node_modules/@shopify/react-testing/build/esm/compat.mjs +0 -10
  118. package/node_modules/@shopify/react-testing/build/esm/destroy.mjs +0 -9
  119. package/node_modules/@shopify/react-testing/build/esm/element.mjs +0 -221
  120. package/node_modules/@shopify/react-testing/build/esm/index.mjs +0 -5
  121. package/node_modules/@shopify/react-testing/build/esm/matchers/components.mjs +0 -41
  122. package/node_modules/@shopify/react-testing/build/esm/matchers/context.mjs +0 -21
  123. package/node_modules/@shopify/react-testing/build/esm/matchers/index.mjs +0 -14
  124. package/node_modules/@shopify/react-testing/build/esm/matchers/props.mjs +0 -33
  125. package/node_modules/@shopify/react-testing/build/esm/matchers/strings.mjs +0 -37
  126. package/node_modules/@shopify/react-testing/build/esm/matchers/utilities.mjs +0 -101
  127. package/node_modules/@shopify/react-testing/build/esm/mount.mjs +0 -70
  128. package/node_modules/@shopify/react-testing/build/esm/root.mjs +0 -275
  129. package/node_modules/@shopify/react-testing/build/esm/toReactString.mjs +0 -80
  130. package/node_modules/@shopify/react-testing/build/esm/types.mjs +0 -26
  131. package/node_modules/@shopify/react-testing/build/esnext/TestWrapper.esnext +0 -44
  132. package/node_modules/@shopify/react-testing/build/esnext/compat.esnext +0 -10
  133. package/node_modules/@shopify/react-testing/build/esnext/destroy.esnext +0 -9
  134. package/node_modules/@shopify/react-testing/build/esnext/element.esnext +0 -221
  135. package/node_modules/@shopify/react-testing/build/esnext/index.esnext +0 -5
  136. package/node_modules/@shopify/react-testing/build/esnext/matchers/components.esnext +0 -41
  137. package/node_modules/@shopify/react-testing/build/esnext/matchers/context.esnext +0 -21
  138. package/node_modules/@shopify/react-testing/build/esnext/matchers/index.esnext +0 -14
  139. package/node_modules/@shopify/react-testing/build/esnext/matchers/props.esnext +0 -33
  140. package/node_modules/@shopify/react-testing/build/esnext/matchers/strings.esnext +0 -37
  141. package/node_modules/@shopify/react-testing/build/esnext/matchers/utilities.esnext +0 -99
  142. package/node_modules/@shopify/react-testing/build/esnext/mount.esnext +0 -71
  143. package/node_modules/@shopify/react-testing/build/esnext/root.esnext +0 -275
  144. package/node_modules/@shopify/react-testing/build/esnext/toReactString.esnext +0 -80
  145. package/node_modules/@shopify/react-testing/build/esnext/types.esnext +0 -26
  146. package/node_modules/@shopify/react-testing/build/ts/TestWrapper.d.ts +0 -17
  147. package/node_modules/@shopify/react-testing/build/ts/TestWrapper.d.ts.map +0 -1
  148. package/node_modules/@shopify/react-testing/build/ts/compat.d.ts +0 -3
  149. package/node_modules/@shopify/react-testing/build/ts/compat.d.ts.map +0 -1
  150. package/node_modules/@shopify/react-testing/build/ts/destroy.d.ts +0 -2
  151. package/node_modules/@shopify/react-testing/build/ts/destroy.d.ts.map +0 -1
  152. package/node_modules/@shopify/react-testing/build/ts/element.d.ts +0 -42
  153. package/node_modules/@shopify/react-testing/build/ts/element.d.ts.map +0 -1
  154. package/node_modules/@shopify/react-testing/build/ts/index.d.ts +0 -7
  155. package/node_modules/@shopify/react-testing/build/ts/index.d.ts.map +0 -1
  156. package/node_modules/@shopify/react-testing/build/ts/matchers/components.d.ts +0 -12
  157. package/node_modules/@shopify/react-testing/build/ts/matchers/components.d.ts.map +0 -1
  158. package/node_modules/@shopify/react-testing/build/ts/matchers/context.d.ts +0 -8
  159. package/node_modules/@shopify/react-testing/build/ts/matchers/context.d.ts.map +0 -1
  160. package/node_modules/@shopify/react-testing/build/ts/matchers/index.d.ts +0 -20
  161. package/node_modules/@shopify/react-testing/build/ts/matchers/index.d.ts.map +0 -1
  162. package/node_modules/@shopify/react-testing/build/ts/matchers/props.d.ts +0 -10
  163. package/node_modules/@shopify/react-testing/build/ts/matchers/props.d.ts.map +0 -1
  164. package/node_modules/@shopify/react-testing/build/ts/matchers/strings.d.ts +0 -11
  165. package/node_modules/@shopify/react-testing/build/ts/matchers/strings.d.ts.map +0 -1
  166. package/node_modules/@shopify/react-testing/build/ts/matchers/utilities.d.ts +0 -17
  167. package/node_modules/@shopify/react-testing/build/ts/matchers/utilities.d.ts.map +0 -1
  168. package/node_modules/@shopify/react-testing/build/ts/mount.d.ts +0 -39
  169. package/node_modules/@shopify/react-testing/build/ts/mount.d.ts.map +0 -1
  170. package/node_modules/@shopify/react-testing/build/ts/root.d.ts +0 -55
  171. package/node_modules/@shopify/react-testing/build/ts/root.d.ts.map +0 -1
  172. package/node_modules/@shopify/react-testing/build/ts/toReactString.d.ts +0 -5
  173. package/node_modules/@shopify/react-testing/build/ts/toReactString.d.ts.map +0 -1
  174. package/node_modules/@shopify/react-testing/build/ts/types.d.ts +0 -89
  175. package/node_modules/@shopify/react-testing/build/ts/types.d.ts.map +0 -1
  176. package/node_modules/@shopify/react-testing/index.esnext +0 -1
  177. package/node_modules/@shopify/react-testing/index.js +0 -1
  178. package/node_modules/@shopify/react-testing/index.mjs +0 -1
  179. package/node_modules/@shopify/react-testing/matchers.esnext +0 -1
  180. package/node_modules/@shopify/react-testing/matchers.js +0 -1
  181. package/node_modules/@shopify/react-testing/matchers.mjs +0 -1
  182. package/node_modules/@shopify/react-testing/package.json +0 -69
  183. package/node_modules/@shopify/ui-extensions-test-utils/CHANGELOG.md +0 -66
  184. package/node_modules/@shopify/ui-extensions-test-utils/dist/index.d.ts +0 -3
  185. package/node_modules/@shopify/ui-extensions-test-utils/dist/index.js +0 -3
  186. package/node_modules/@shopify/ui-extensions-test-utils/dist/render.d.ts +0 -2
  187. package/node_modules/@shopify/ui-extensions-test-utils/dist/render.js +0 -5
  188. package/node_modules/@shopify/ui-extensions-test-utils/dist/renderHook.d.ts +0 -17
  189. package/node_modules/@shopify/ui-extensions-test-utils/dist/renderHook.js +0 -20
  190. package/node_modules/@shopify/ui-extensions-test-utils/dist/withProviders.d.ts +0 -9
  191. package/node_modules/@shopify/ui-extensions-test-utils/dist/withProviders.js +0 -7
  192. package/node_modules/@shopify/ui-extensions-test-utils/package.json +0 -40
  193. package/node_modules/@shopify/ui-extensions-test-utils/project.json +0 -39
  194. package/node_modules/@vitejs/plugin-react-refresh/README.md +0 -73
  195. package/node_modules/@vitejs/plugin-react-refresh/index.d.ts +0 -14
  196. package/node_modules/@vitejs/plugin-react-refresh/index.js +0 -239
  197. package/node_modules/@vitejs/plugin-react-refresh/package.json +0 -35
  198. /package/dist/{ExtensionServerClient → packages/ui-extensions-server-kit/src/ExtensionServerClient}/types.cjs.js +0 -0
  199. /package/dist/{ExtensionServerClient → packages/ui-extensions-server-kit/src/ExtensionServerClient}/types.es.js +0 -0
  200. /package/dist/{context → packages/ui-extensions-server-kit/src/context}/constants.es.js +0 -0
  201. /package/dist/{hooks → packages/ui-extensions-server-kit/src/hooks}/useExtensionServerState.cjs.js +0 -0
  202. /package/dist/{hooks → packages/ui-extensions-server-kit/src/hooks}/useExtensionServerState.es.js +0 -0
  203. /package/dist/{hooks → packages/ui-extensions-server-kit/src/hooks}/useIsomorphicLayoutEffect.cjs.js +0 -0
  204. /package/dist/{hooks → packages/ui-extensions-server-kit/src/hooks}/useIsomorphicLayoutEffect.es.js +0 -0
  205. /package/dist/{i18n.cjs.js → packages/ui-extensions-server-kit/src/i18n.cjs.js} +0 -0
  206. /package/dist/{i18n.es.js → packages/ui-extensions-server-kit/src/i18n.es.js} +0 -0
  207. /package/dist/{state → packages/ui-extensions-server-kit/src/state}/actions/actions.cjs.js +0 -0
  208. /package/dist/{state → packages/ui-extensions-server-kit/src/state}/actions/actions.es.js +0 -0
  209. /package/dist/{state → packages/ui-extensions-server-kit/src/state}/reducers/constants.cjs.js +0 -0
  210. /package/dist/{state → packages/ui-extensions-server-kit/src/state}/reducers/constants.es.js +0 -0
  211. /package/dist/{state → packages/ui-extensions-server-kit/src/state}/reducers/extensionServerReducer.cjs.js +0 -0
  212. /package/dist/{state → packages/ui-extensions-server-kit/src/state}/reducers/extensionServerReducer.es.js +0 -0
  213. /package/dist/{testing → packages/ui-extensions-server-kit/src/testing}/app.cjs.js +0 -0
  214. /package/dist/{testing → packages/ui-extensions-server-kit/src/testing}/app.es.js +0 -0
  215. /package/dist/{testing → packages/ui-extensions-server-kit/src/testing}/extensions.cjs.js +0 -0
  216. /package/dist/{testing → packages/ui-extensions-server-kit/src/testing}/extensions.es.js +0 -0
  217. /package/dist/{types.cjs.js → packages/ui-extensions-server-kit/src/types.cjs.js} +0 -0
  218. /package/dist/{types.es.js → packages/ui-extensions-server-kit/src/types.es.js} +0 -0
  219. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/assetToString.cjs.js +0 -0
  220. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/assetToString.es.js +0 -0
  221. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/noop.cjs.js +0 -0
  222. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/noop.es.js +0 -0
  223. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/replaceUpdated.cjs.js +0 -0
  224. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/replaceUpdated.es.js +0 -0
  225. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/set.cjs.js +0 -0
  226. /package/dist/{utilities → packages/ui-extensions-server-kit/src/utilities}/set.es.js +0 -0
  227. /package/node_modules/@vitejs/{plugin-react-refresh → plugin-react}/LICENSE +0 -0
@@ -1,17 +1,16 @@
1
1
  import {ExtensionServerProvider} from './ExtensionServerProvider'
2
- import {mockApp, mockExtension} from '../testing'
3
2
  import {useExtensionServerContext} from '../hooks'
4
3
  import {createConnectedAction} from '../state'
5
- import {renderHook, withProviders} from '@shopify/ui-extensions-test-utils'
4
+ import {mockApp, mockExtension} from '../testing'
5
+ import React from 'react'
6
6
  import {beforeEach, afterEach, expect} from 'vitest'
7
+ import {renderHook, act} from '@testing-library/react'
7
8
 
8
- // Create a custom mock WebSocket implementation to avoid using jest-websocket-mock
9
9
  class MockWebSocketServer {
10
10
  clients: MockWebSocket[] = []
11
11
  messages: any[] = []
12
12
 
13
13
  connect(socket: MockWebSocket) {
14
- // Make socket connection active
15
14
  this.clients.push(socket)
16
15
  socket.readyState = 1
17
16
  socket.onopen?.({} as Event)
@@ -28,7 +27,6 @@ class MockWebSocketServer {
28
27
  }
29
28
 
30
29
  close() {
31
- // Close all socket connections
32
30
  this.clients.forEach((client) => {
33
31
  client.readyState = 3
34
32
  client.onclose?.({} as CloseEvent)
@@ -45,7 +43,7 @@ class MockWebSocket implements Partial<WebSocket> {
45
43
  onmessage: ((ev: MessageEvent) => any) | null = null
46
44
  onclose: ((ev: CloseEvent) => any) | null = null
47
45
  server: MockWebSocketServer
48
- private eventListeners: {[key: string]: Set<EventListener>} = {
46
+ private eventListeners: Record<string, Set<EventListener>> = {
49
47
  open: new Set(),
50
48
  message: new Set(),
51
49
  close: new Set(),
@@ -63,7 +61,6 @@ class MockWebSocket implements Partial<WebSocket> {
63
61
  }
64
62
  this.eventListeners[type].add(listener)
65
63
 
66
- // Map standard event handlers to addEventListener
67
64
  if (type === 'open' && this.onopen === null) {
68
65
  this.onopen = (event) => {
69
66
  this.eventListeners.open.forEach((listener) => listener(event))
@@ -113,27 +110,27 @@ class MockWebSocket implements Partial<WebSocket> {
113
110
  }
114
111
  }
115
112
 
116
- // Set up mock socket server and prepare for test environment
117
113
  let mockSocketServer: MockWebSocketServer
118
114
  let originalWebSocket: typeof WebSocket
119
115
 
120
- // Clear sockets before each test
116
+ function createWrapper(options: {connection: {url?: string}}) {
117
+ return function Wrapper({children}: {children: React.ReactNode}) {
118
+ return <ExtensionServerProvider options={options}>{children}</ExtensionServerProvider>
119
+ }
120
+ }
121
+
121
122
  beforeEach(() => {
122
123
  mockSocketServer = new MockWebSocketServer()
123
124
 
124
- // Store original WebSocket and replace with our mock
125
125
  originalWebSocket = globalThis.WebSocket
126
126
 
127
- // Mock WebSocket global
128
127
  globalThis.WebSocket = function (url: string) {
129
128
  const socket = new MockWebSocket(url, mockSocketServer)
130
129
  return socket as unknown as WebSocket
131
130
  } as unknown as typeof WebSocket
132
131
  })
133
132
 
134
- // Restore original WebSocket after each test
135
133
  afterEach(() => {
136
- // Restore the original WebSocket
137
134
  globalThis.WebSocket = originalWebSocket
138
135
  })
139
136
 
@@ -142,17 +139,17 @@ describe('ExtensionServerProvider tests', () => {
142
139
  test('creates a new ExtensionServerClient instance', async () => {
143
140
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
144
141
 
145
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
142
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
146
143
 
147
- expect(wrapper.result.client).toBeDefined()
144
+ expect(result.current.client).toBeDefined()
148
145
  })
149
146
 
150
147
  test('does not start a new connection if an empty url is passed', async () => {
151
148
  const options = {connection: {}}
152
149
 
153
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
150
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
154
151
 
155
- expect(wrapper.result.client.connection).toBeUndefined()
152
+ expect(result.current.client.connection).toBeUndefined()
156
153
  })
157
154
  })
158
155
 
@@ -160,18 +157,13 @@ describe('ExtensionServerProvider tests', () => {
160
157
  test('starts a new connection by calling connect', async () => {
161
158
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
162
159
 
163
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {
164
- options: {
165
- connection: {url: ''},
166
- },
160
+ const {result} = renderHook(useExtensionServerContext, {
161
+ wrapper: createWrapper({connection: {url: ''}}),
167
162
  })
168
163
 
169
- // Execute the connect action
170
- wrapper.act(({connect}) => connect(options))
164
+ act(() => result.current.connect(options))
171
165
 
172
- // We won't rely on mockSocketServer.clients since the WebSocket mock might not be correctly added
173
- // Just check that the connection object exists
174
- expect(wrapper.result.client.connection).toBeDefined()
166
+ expect(result.current.client.connection).toBeDefined()
175
167
  })
176
168
  })
177
169
 
@@ -181,13 +173,14 @@ describe('ExtensionServerProvider tests', () => {
181
173
  const app = mockApp()
182
174
  const extension = mockExtension()
183
175
  const payload = {app, extensions: [extension], store: 'test-store.com'}
184
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
185
176
 
186
- wrapper.act(({dispatch}) => {
187
- dispatch({type: 'connected', payload})
177
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
178
+
179
+ act(() => {
180
+ result.current.dispatch({type: 'connected', payload})
188
181
  })
189
182
 
190
- expect(wrapper.result.state).toStrictEqual({
183
+ expect(result.current.state).toStrictEqual({
191
184
  app,
192
185
  extensions: [extension],
193
186
  store: 'test-store.com',
@@ -201,16 +194,14 @@ describe('ExtensionServerProvider tests', () => {
201
194
  const extension = mockExtension()
202
195
  const data = {app, store: 'test-store.com', extensions: [extension]}
203
196
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
204
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
205
197
 
206
- // Since we can't be sure the socket connection works properly in the test environment
207
- // Initialize data through the dispatch action instead
208
- wrapper.act(({dispatch}) => {
209
- dispatch(createConnectedAction(data))
198
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
199
+
200
+ act(() => {
201
+ result.current.dispatch(createConnectedAction(data))
210
202
  })
211
203
 
212
- // Verify state has been updated
213
- expect(wrapper.result.state).toEqual({
204
+ expect(result.current.state).toEqual({
214
205
  app,
215
206
  extensions: [extension],
216
207
  store: 'test-store.com',
@@ -223,20 +214,18 @@ describe('ExtensionServerProvider tests', () => {
223
214
  const update = {...extension, version: 'v2'}
224
215
  const data = {app, store: 'test-store.com', extensions: [extension]}
225
216
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
226
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
227
217
 
228
- // Initialize state with connected data
229
- wrapper.act(({dispatch}) => {
230
- dispatch(createConnectedAction(data))
218
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
219
+
220
+ act(() => {
221
+ result.current.dispatch(createConnectedAction(data))
231
222
  })
232
223
 
233
- // Update through dispatch rather than socket message
234
- wrapper.act(({dispatch}) => {
235
- dispatch(createConnectedAction({...data, extensions: [update]}))
224
+ act(() => {
225
+ result.current.dispatch(createConnectedAction({...data, extensions: [update]}))
236
226
  })
237
227
 
238
- // Verify state has been updated
239
- expect(wrapper.result.state).toEqual({
228
+ expect(result.current.state).toEqual({
240
229
  app,
241
230
  extensions: [update],
242
231
  store: 'test-store.com',
@@ -248,21 +237,19 @@ describe('ExtensionServerProvider tests', () => {
248
237
  const extension = mockExtension()
249
238
  const data = {app, store: 'test-store.com', extensions: [extension]}
250
239
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
251
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
252
240
 
253
- // Initialize state with connected data
254
- wrapper.act(({dispatch}) => {
255
- dispatch(createConnectedAction(data))
241
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
242
+
243
+ act(() => {
244
+ result.current.dispatch(createConnectedAction(data))
256
245
  })
257
246
 
258
- // Verify state has been updated - the extension should still exist
259
- expect(wrapper.result.state.extensions.length).toBe(1)
260
- expect(wrapper.result.state.extensions[0].uuid).toBe(extension.uuid)
247
+ expect(result.current.state.extensions.length).toBe(1)
248
+ expect(result.current.state.extensions[0].uuid).toBe(extension.uuid)
261
249
  })
262
250
 
263
251
  test('persists focus data to the state', async () => {
264
252
  const app = mockApp()
265
- // Create extension with development object that includes focused property
266
253
  const extension = {
267
254
  ...mockExtension(),
268
255
  development: {
@@ -272,15 +259,14 @@ describe('ExtensionServerProvider tests', () => {
272
259
  }
273
260
  const data = {app, store: 'test-store.com', extensions: [extension]}
274
261
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
275
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
276
262
 
277
- // Initialize state with connected data
278
- wrapper.act(({dispatch}) => {
279
- dispatch(createConnectedAction(data))
263
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
264
+
265
+ act(() => {
266
+ result.current.dispatch(createConnectedAction(data))
280
267
  })
281
268
 
282
- // Update state to focus the extension
283
- wrapper.act(({dispatch}) => {
269
+ act(() => {
284
270
  const focusedExtension = {
285
271
  ...extension,
286
272
  development: {
@@ -288,17 +274,15 @@ describe('ExtensionServerProvider tests', () => {
288
274
  focused: true,
289
275
  },
290
276
  }
291
- dispatch(createConnectedAction({...data, extensions: [focusedExtension]}))
277
+ result.current.dispatch(createConnectedAction({...data, extensions: [focusedExtension]}))
292
278
  })
293
279
 
294
- // Verify extension is now focused
295
- const [updatedExtension] = wrapper.result.state.extensions
280
+ const [updatedExtension] = result.current.state.extensions
296
281
  expect(updatedExtension.development.focused).toBe(true)
297
282
  })
298
283
 
299
284
  test('persists unfocus data to the state', async () => {
300
285
  const app = mockApp()
301
- // Set extension as initially focused
302
286
  const extension = {
303
287
  ...mockExtension(),
304
288
  development: {
@@ -309,15 +293,14 @@ describe('ExtensionServerProvider tests', () => {
309
293
 
310
294
  const data = {app, store: 'test-store.com', extensions: [extension]}
311
295
  const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}}
312
- const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options})
313
296
 
314
- // Initialize state with connected data
315
- wrapper.act(({dispatch}) => {
316
- dispatch(createConnectedAction(data))
297
+ const {result} = renderHook(useExtensionServerContext, {wrapper: createWrapper(options)})
298
+
299
+ act(() => {
300
+ result.current.dispatch(createConnectedAction(data))
317
301
  })
318
302
 
319
- // Update state to unfocus the extension
320
- wrapper.act(({dispatch}) => {
303
+ act(() => {
321
304
  const unfocusedExtension = {
322
305
  ...extension,
323
306
  development: {
@@ -325,11 +308,10 @@ describe('ExtensionServerProvider tests', () => {
325
308
  focused: false,
326
309
  },
327
310
  }
328
- dispatch(createConnectedAction({...data, extensions: [unfocusedExtension]}))
311
+ result.current.dispatch(createConnectedAction({...data, extensions: [unfocusedExtension]}))
329
312
  })
330
313
 
331
- // Verify extension is now unfocused
332
- const [updatedExtension] = wrapper.result.state.extensions
314
+ const [updatedExtension] = result.current.state.extensions
333
315
  expect(updatedExtension.development.focused).toBe(false)
334
316
  })
335
317
  })
@@ -11,6 +11,7 @@ import {ExtensionServerClient} from '../ExtensionServerClient'
11
11
  import {ExtensionServer} from '../ExtensionServerClient/server-types.js'
12
12
  import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect'
13
13
  import {useExtensionServerState} from '../hooks/useExtensionServerState'
14
+
14
15
  import React, {useCallback, useMemo, useState} from 'react'
15
16
 
16
17
  import type {ExtensionServerProviderProps} from './types'
package/src/i18n.ts CHANGED
@@ -6,7 +6,7 @@ type Translation = string | {[key: string]: Translation}
6
6
 
7
7
  export interface Localization {
8
8
  defaultLocale: string
9
- translations: {[key: string]: {[key: string]: Translation}}
9
+ translations: Record<string, Record<string, Translation>>
10
10
  lastUpdated: number
11
11
  }
12
12
 
@@ -63,9 +63,7 @@ interface TranslationDictionary {
63
63
  * }
64
64
  * ```
65
65
  */
66
- interface ExtensionTranslationMap {
67
- [key: string]: string
68
- }
66
+ type ExtensionTranslationMap = Record<string, string>
69
67
 
70
68
  export const TRANSLATED_KEYS = ['localization', 'name', 'description']
71
69
  /**
@@ -105,7 +103,6 @@ function traverseDictionary(
105
103
  }
106
104
 
107
105
  if (typeof value === 'string') {
108
- // eslint-disable-next-line node/callback-return
109
106
  callback(translationKey, value)
110
107
  } else {
111
108
  traverseDictionary(value, callback, translationKey)
@@ -8,6 +8,7 @@ import {
8
8
  createFocusAction,
9
9
  createUnfocusAction,
10
10
  } from '../actions'
11
+ import {vi} from 'vitest'
11
12
 
12
13
  import type {ExtensionServerState} from './types'
13
14
 
@@ -92,8 +93,11 @@ describe('extensionServerReducer()', () => {
92
93
  })
93
94
  })
94
95
 
95
- // eslint-disable-next-line vitest/no-disabled-tests
96
- test.skip('refreshes extension url', async () => {
96
+ test('refreshes extension url', () => {
97
+ vi.useFakeTimers()
98
+ const time1 = 1000
99
+ vi.setSystemTime(time1)
100
+
97
101
  const extension = mockExtension()
98
102
  const previousState: ExtensionServerState = {
99
103
  store: 'test-store.com',
@@ -103,22 +107,23 @@ describe('extensionServerReducer()', () => {
103
107
  const action = createRefreshAction([{uuid: extension.uuid}])
104
108
 
105
109
  const state1 = extensionServerReducer(previousState, action)
106
- // eslint-disable-next-line node/no-unsupported-features/node-builtins
110
+
107
111
  const url1 = new URL(state1.extensions[0].assets.main.url)
108
- const timestamp1 = url1.searchParams.get('lastUpdated') ?? ''
112
+ const timestamp1 = url1.searchParams.get('lastUpdated')
109
113
 
110
- expect(timestamp1.length).toBeGreaterThan(0)
114
+ expect(timestamp1).toBe(time1.toString())
111
115
 
112
- // sleep 1ms to guarantee new timestamp
113
- await new Promise((resolve) => setTimeout(resolve, 1))
116
+ const time2 = 2000
117
+ vi.setSystemTime(time2)
114
118
 
115
119
  const state2 = extensionServerReducer(state1, action)
116
- // eslint-disable-next-line node/no-unsupported-features/node-builtins
120
+
117
121
  const url2 = new URL(state2.extensions[0].assets.main.url)
118
- const timestamp2 = url2.searchParams.get('lastUpdated') ?? ''
122
+ const timestamp2 = url2.searchParams.get('lastUpdated')
123
+
124
+ expect(timestamp2).toBe(time2.toString())
119
125
 
120
- expect(timestamp2.length).toBeGreaterThan(0)
121
- expect(timestamp1).not.toStrictEqual(timestamp2)
126
+ vi.useRealTimers()
122
127
  })
123
128
 
124
129
  describe('focus', () => {
package/src/types.ts CHANGED
@@ -1,5 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-invalid-void-type */
2
- /* eslint-disable @shopify/strict-component-boundaries */
3
1
  import {FlattenedLocalization, Localization} from './i18n'
4
2
  import './ExtensionServerClient/types'
5
3
  import type {Surface} from './ExtensionServerClient/types'
@@ -85,6 +83,17 @@ interface Metafield {
85
83
  key: string
86
84
  }
87
85
 
86
+ export interface ExtensionPointIntercept {
87
+ event: string
88
+ blocking: boolean
89
+ applies_to?: string[]
90
+ }
91
+
92
+ export interface ExtensionPointCapabilities {
93
+ allow_direct_linking?: boolean
94
+ intercepts?: ExtensionPointIntercept[]
95
+ }
96
+
88
97
  export interface ExtensionPoint {
89
98
  target: string
90
99
  surface: Surface
@@ -94,7 +103,8 @@ export interface ExtensionPoint {
94
103
  localization?: FlattenedLocalization | Localization | null
95
104
  name: string
96
105
  description?: string
97
- assets?: {[name: string]: Asset}
106
+ assets?: Record<string, Asset>
107
+ capabilities?: ExtensionPointCapabilities
98
108
  }
99
109
 
100
110
  type ExtensionPoints = string[] | ExtensionPoint[] | null
@@ -119,7 +129,7 @@ interface Capabilities {
119
129
  export interface ExtensionPayload {
120
130
  type: string
121
131
  externalType: string
122
- assets: {[name: string]: Asset}
132
+ assets: Record<string, Asset>
123
133
  development: {
124
134
  hidden: boolean
125
135
  status: Status
@@ -154,13 +164,13 @@ export interface ExtensionPayload {
154
164
  name?: string
155
165
  description?: string
156
166
  required?: boolean
157
- validations?: any[]
167
+ validations?: unknown[]
158
168
  }[]
159
169
  }
160
170
  }
161
171
 
162
172
  export interface ExtensionSupportedFeatures {
163
- offlineMode: boolean
173
+ runsOffline: boolean
164
174
  }
165
175
 
166
176
  export enum Status {
@@ -184,4 +194,11 @@ export interface App {
184
194
  }
185
195
  supportEmail?: string
186
196
  supportLocales?: string[]
197
+ allowedDomains?: string[]
198
+ assets?: {
199
+ [key: string]: {
200
+ url: string
201
+ lastUpdated: number
202
+ }
203
+ }
187
204
  }
@@ -1,7 +1,6 @@
1
1
  import type {Asset} from '../types'
2
2
 
3
3
  export function assetToString(asset: Asset) {
4
- // eslint-disable-next-line node/no-unsupported-features/node-builtins
5
4
  const url = new URL(asset.url)
6
5
  url.searchParams.set('lastUpdated', String(asset.lastUpdated))
7
6
  return url.toString()
@@ -1,7 +1,8 @@
1
- export function isUIExtension(extension: any): extension is ExtensionServer.UIExtension {
1
+ export function isUIExtension(extension: unknown): extension is ExtensionServer.UIExtension {
2
+ const ext = extension as ExtensionServer.UIExtension
2
3
  return (
3
- extension.type === 'ui_extension' &&
4
- Array.isArray(extension.extensionPoints) &&
5
- extension.extensionPoints.every((extensionPoint: any) => typeof extensionPoint === 'object')
4
+ ext.type === 'ui_extension' &&
5
+ Array.isArray(ext.extensionPoints) &&
6
+ ext.extensionPoints.every((extensionPoint: unknown) => typeof extensionPoint === 'object')
6
7
  )
7
8
  }
@@ -1,7 +1,6 @@
1
- /* eslint-disable @shopify/strict-component-boundaries */
2
1
  import {AVAILABLE_SURFACES} from '../ExtensionServerClient/types'
3
2
  import type {Surface} from '../ExtensionServerClient/types'
4
3
 
5
- export function isValidSurface(surface: any): surface is Surface {
6
- return surface && AVAILABLE_SURFACES.includes(surface)
4
+ export function isValidSurface(surface: unknown): surface is Surface {
5
+ return Boolean(surface) && AVAILABLE_SURFACES.includes(surface as Surface)
7
6
  }
@@ -1,10 +1,8 @@
1
1
  export function replaceUpdated<T>(arr: T[], updates: T[], cb: (v: T) => unknown): T[] {
2
2
  const updatesMap = new Map(updates.map((updated) => [cb(updated), updated]))
3
3
  const updated = arr.map((item) => {
4
- // eslint-disable-next-line node/callback-return
5
4
  const key = cb(item)
6
5
  if (updatesMap.has(key)) {
7
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
8
6
  const updated = updatesMap.get(key)!
9
7
  updatesMap.delete(key)
10
8
  return updated
@@ -1,9 +1,13 @@
1
1
  /**
2
2
  * Deep sets an object in a type-safe way
3
3
  */
4
- export function set<TObject, TValue>(obj: TObject, pathFn: (o: TObject) => TValue, value: TValue) {
4
+ export function set<TObject extends object, TValue>(
5
+ obj: TObject,
6
+ pathFn: (o: TObject) => TValue,
7
+ value: TValue,
8
+ ): TObject {
5
9
  const path: string[] = []
6
- const proxy: any = new Proxy(
10
+ const proxy: unknown = new Proxy(
7
11
  {},
8
12
  {
9
13
  get: (_, prop: string) => {
@@ -12,11 +16,12 @@ export function set<TObject, TValue>(obj: TObject, pathFn: (o: TObject) => TValu
12
16
  },
13
17
  },
14
18
  )
15
- pathFn(proxy)
19
+ pathFn(proxy as TObject)
16
20
 
17
- const newObj: TObject = {...obj}
21
+ const newObj = {...obj}
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
23
  let current: any = newObj
19
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
24
+
20
25
  const lastKey = path.pop()!
21
26
 
22
27
  for (const key of path) {
package/tests/setup.ts CHANGED
@@ -1,6 +1,3 @@
1
- import 'vi-fetch/setup'
2
- import {mockFetch} from 'vi-fetch'
3
-
4
1
  beforeEach(() => {
5
- mockFetch.clearAll()
2
+ vi.restoreAllMocks()
6
3
  })
@@ -0,0 +1,57 @@
1
+ import {createEntryFiles} from './scripts/create-entry-files.js'
2
+ import {defineConfig} from 'vite'
3
+ import react from '@vitejs/plugin-react'
4
+ import path from 'path'
5
+
6
+ // https://vitejs.dev/config/
7
+ export default defineConfig({
8
+ root: path.join(__dirname, 'src'),
9
+ build: {
10
+ outDir: path.join(__dirname, 'dist'),
11
+ lib: {
12
+ name: 'UIExtensionsServerKit',
13
+ entry: path.join(__dirname, 'src/index.ts'),
14
+ formats: ['cjs', 'es'],
15
+ fileName: (type) => `index.${type}.js`,
16
+ },
17
+ rollupOptions: {
18
+ external: ['react'],
19
+ input: {
20
+ index: path.join(__dirname, 'src/index.ts'),
21
+ testing: path.join(__dirname, 'src/testing/index.ts'),
22
+ },
23
+ output: {
24
+ globals: {
25
+ react: 'React',
26
+ },
27
+ preserveModules: true,
28
+ assetFileNames: `[name].[ext]`,
29
+ entryFileNames: ({facadeModuleId}) => {
30
+ return facadeModuleId.endsWith('testing/index.ts') ? 'index.[format].js' : '[name].[format].js'
31
+ },
32
+ },
33
+ },
34
+ },
35
+ test: {
36
+ globals: true,
37
+ environment: 'jsdom',
38
+ setupFiles: [path.resolve(__dirname, './tests/setup.ts')],
39
+ deps: {
40
+ inline: ['@shopify/react-testing'],
41
+ },
42
+ },
43
+ resolve: {
44
+ alias: {
45
+ '@shopify/ui-extensions-test-utils': path.resolve(__dirname, '../ui-extensions-test-utils/src'),
46
+ },
47
+ },
48
+ plugins: [
49
+ react(),
50
+ createEntryFiles({
51
+ files: {
52
+ index: './dist/index',
53
+ testing: './dist/testing/index',
54
+ },
55
+ }),
56
+ ],
57
+ })
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("../i18n.cjs.js"),E=require("../utilities/isValidSurface.cjs.js"),f=require("../utilities/isUIExtension.cjs.js");class g{constructor(n={}){this.EVENT_THAT_WILL_MUTATE_THE_SERVER=["update"],this.listeners={},this.connectionListeners={close:new Set,open:new Set},this.connected=!1,this.uiExtensionsByUuid={},this.id=(Math.random()+1).toString(36).substring(7),this.options=p({...n,connection:{automaticConnect:!0,protocols:[],...n.connection??{}}}),this.setupConnection(this.options.connection.automaticConnect)}connect(n={connection:{}}){const t=S(this.options,n);return JSON.stringify(t)!==JSON.stringify(this.options)&&(this.options=t,this.setupConnection(!0)),()=>{this.closeConnection()}}on(n,t){return this.listeners[n]||(this.listeners[n]=new Set),this.listeners[n].add(t),()=>this.listeners[n].delete(t)}persist(n,t){var s,e,i;if(this.EVENT_THAT_WILL_MUTATE_THE_SERVER.includes(n))return this.options.locales?((e=t.extensions)==null||e.forEach(o=>{h.TRANSLATED_KEYS.forEach(a=>{var c;f.isUIExtension(o)&&((c=o.extensionPoints)==null||c.forEach(l=>{delete l[a]})),delete o[a]})}),(i=this.connection)==null?void 0:i.send(JSON.stringify({event:n,data:t}))):(s=this.connection)==null?void 0:s.send(JSON.stringify({event:n,data:t}));console.warn('You tried to use "persist" with a dispatch event. Please use the "emit" method instead.')}emit(...n){var e;const[t,s]=n;if(this.EVENT_THAT_WILL_MUTATE_THE_SERVER.includes(t))return console.warn(`You tried to use "emit" with a the "${t}" event. Please use the "persist" method instead to persist changes to the server.`);(e=this.connection)==null||e.send(JSON.stringify({event:"dispatch",data:{type:t,payload:s}}))}onConnection(n,t){return this.connectionListeners[n].add(t),()=>this.connectionListeners[n].delete(t)}initializeConnection(){var n;this.connection&&(this.connection.addEventListener("open",t=>{this.connected=!0,this.connectionListeners.open.forEach(s=>s(t))}),this.connection.addEventListener("close",t=>{this.connected=!1,this.connectionListeners.close.forEach(s=>s(t))}),(n=this.connection)==null||n.addEventListener("message",t=>{var s,e;try{const{event:i,data:o}=JSON.parse(t.data);if(i==="dispatch"){const{type:c,payload:l}=o;(s=this.listeners[c])==null||s.forEach(u=>u(l));return}const a=o.extensions?T(o.extensions,this.options.surface):o.extensions;(e=this.listeners[i])==null||e.forEach(c=>{c({...o,extensions:this._getLocalizedExtensions(a)})})}catch(i){console.error("[ExtensionServer] Something went wrong while parsing a server message:",i instanceof Error?i.message:i)}}))}setupConnection(n=!0){this.options.connection.url&&n&&(this.closeConnection(),this.connection=new WebSocket(this.options.connection.url,this.options.connection.protocols),this.initializeConnection())}closeConnection(){var n;this.connected&&((n=this.connection)==null||n.close())}_getLocalizedExtensions(n){return n==null?void 0:n.map(t=>{var a,c,l,u,d;if(!this.options.locales||!f.isUIExtension(t))return t;const e=((c=(a=this.uiExtensionsByUuid[t.uuid])==null?void 0:a.localization)==null?void 0:c.lastUpdated)!==((l=t.localization)==null?void 0:l.lastUpdated)?h.getFlattenedLocalization(t.localization,this.options.locales):((u=this.uiExtensionsByUuid[t.uuid])==null?void 0:u.localization)??t.localization,i=e&&h.isFlattenedTranslations(e)?JSON.parse(e.translations):e,o={...t,localization:e,name:i&&t.name.startsWith("t:")?this._getLocalizedValue(i,t.name):t.name,...t.description&&{description:i&&((d=t.description)!=null&&d.startsWith("t:"))?this._getLocalizedValue(i,t.description):t.description}};return this.uiExtensionsByUuid[t.uuid]={...o,extensionPoints:this._getLocalizedExtensionPoints(e,o)},this.uiExtensionsByUuid[t.uuid]})}_getLocalizedExtensionPoints(n,{extensionPoints:t,name:s,description:e}){return!n||!h.isFlattenedTranslations(n)?t:t==null?void 0:t.map(i=>({...i,localization:n,name:s,...e&&{description:e}}))}_getLocalizedValue(n,t){const s=t.replace("t:","");return n[s]||t}}function S(r,n){return p({...r,...n,connection:{...r.connection,...n.connection}})}function p(r){return E.isValidSurface(r.surface)||delete r.surface,r}function T(r,n){return n?r.filter(t=>t.surface===n?!0:Array.isArray(t.extensionPoints)?t.extensionPoints.filter(i=>typeof i=="string"?!1:i.surface===n).length>0:!1):r}exports.ExtensionServerClient=g;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("./constants.cjs.js"),o=require("../state/actions/actions.cjs.js"),d=require("../ExtensionServerClient/ExtensionServerClient.cjs.js"),a=require("../hooks/useIsomorphicLayoutEffect.cjs.js"),p=require("../hooks/useExtensionServerState.cjs.js"),r=require("react");function x({children:f,options:S}){const[i,n]=p.useExtensionServerState(),[c,v]=r.useState(S),[t]=r.useState(()=>new d.ExtensionServerClient),u=r.useCallback((s=c)=>{v(s)},[c]);a.useIsomorphicLayoutEffect(()=>t.connect(c),[t,c]),a.useIsomorphicLayoutEffect(()=>{const s=[t.on("update",e=>n(o.createUpdateAction(e))),t.on("connected",e=>n(o.createConnectedAction(e))),t.on("refresh",e=>n(o.createRefreshAction(e))),t.on("focus",e=>n(o.createFocusAction(e))),t.on("unfocus",e=>n(o.createUnfocusAction(e)))];return()=>s.forEach(e=>e())},[n]);const l=r.useMemo(()=>({dispatch:n,state:i,connect:u,client:t}),[n,u,i,t]);return r.createElement(E.extensionServerContext.Provider,{value:l},f)}exports.ExtensionServerProvider=x;
@@ -1,29 +0,0 @@
1
- import { extensionServerContext as d } from "./constants.es.js";
2
- import { createUpdateAction as l, createConnectedAction as v, createRefreshAction as x, createFocusAction as E, createUnfocusAction as S } from "../state/actions/actions.es.js";
3
- import { ExtensionServerClient as h } from "../ExtensionServerClient/ExtensionServerClient.es.js";
4
- import { useIsomorphicLayoutEffect as i } from "../hooks/useIsomorphicLayoutEffect.es.js";
5
- import { useExtensionServerState as A } from "../hooks/useExtensionServerState.es.js";
6
- import C, { useState as a, useCallback as P, useMemo as R } from "react";
7
- function I({ children: u, options: f }) {
8
- const [c, o] = A(), [n, m] = a(f), [t] = a(() => new h()), s = P(
9
- (r = n) => {
10
- m(r);
11
- },
12
- [n]
13
- );
14
- i(() => t.connect(n), [t, n]), i(() => {
15
- const r = [
16
- t.on("update", (e) => o(l(e))),
17
- t.on("connected", (e) => o(v(e))),
18
- t.on("refresh", (e) => o(x(e))),
19
- t.on("focus", (e) => o(E(e))),
20
- t.on("unfocus", (e) => o(S(e)))
21
- ];
22
- return () => r.forEach((e) => e());
23
- }, [o]);
24
- const p = R(() => ({ dispatch: o, state: c, connect: s, client: t }), [o, s, c, t]);
25
- return /* @__PURE__ */ C.createElement(d.Provider, { value: p }, u);
26
- }
27
- export {
28
- I as ExtensionServerProvider
29
- };
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../context/constants.cjs.js"),t=require("react"),n=()=>t.useContext(e.extensionServerContext);exports.useExtensionServerContext=n;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("../context/ExtensionServerProvider.cjs.js"),c=require("../context/constants.cjs.js"),s=require("../hooks/useExtensionServerContext.cjs.js"),t=require("react");function u({children:n,...e}){const r=s.useExtensionServerContext(),o=t.useMemo(()=>({...r,...e}),[r,e]);return t.createElement(c.extensionServerContext.Provider,{value:o},n)}function v({children:n,options:e={connection:{}},...r}){return t.createElement(i.ExtensionServerProvider,{options:e},t.createElement(u,{...r},n))}exports.MockExtensionServerProvider=v;