@hexclave/shared 1.0.3 → 1.0.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 (343) hide show
  1. package/dist/ai/unified-prompts/reminders.js +4 -3
  2. package/dist/ai/unified-prompts/reminders.js.map +1 -1
  3. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +3 -1
  4. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
  5. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +216 -29
  6. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  7. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -1
  8. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +1 -0
  9. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -1
  10. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +18 -6
  11. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +23 -8
  12. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
  13. package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +1 -1
  14. package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -1
  15. package/dist/config/schema.d.ts +71 -71
  16. package/dist/config/schema.d.ts.map +1 -1
  17. package/dist/config/schema.js +5 -5
  18. package/dist/config/schema.js.map +1 -1
  19. package/dist/config-authoring.d.ts +4 -4
  20. package/dist/config-authoring.d.ts.map +1 -1
  21. package/dist/config-authoring.js +2 -2
  22. package/dist/config-authoring.js.map +1 -1
  23. package/dist/config-rendering.d.ts +4 -4
  24. package/dist/config-rendering.d.ts.map +1 -1
  25. package/dist/config-rendering.js +19 -18
  26. package/dist/config-rendering.js.map +1 -1
  27. package/dist/esm/ai/unified-prompts/reminders.js +4 -3
  28. package/dist/esm/ai/unified-prompts/reminders.js.map +1 -1
  29. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +3 -1
  30. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
  31. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +215 -30
  32. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  33. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -1
  34. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +1 -0
  35. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -1
  36. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +18 -6
  37. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +23 -8
  38. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
  39. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +1 -1
  40. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -1
  41. package/dist/esm/config/schema.d.ts +71 -71
  42. package/dist/esm/config/schema.d.ts.map +1 -1
  43. package/dist/esm/config/schema.js +5 -5
  44. package/dist/esm/config/schema.js.map +1 -1
  45. package/dist/esm/config-authoring.d.ts +4 -4
  46. package/dist/esm/config-authoring.d.ts.map +1 -1
  47. package/dist/esm/config-authoring.js +2 -2
  48. package/dist/esm/config-authoring.js.map +1 -1
  49. package/dist/esm/config-rendering.d.ts +4 -4
  50. package/dist/esm/config-rendering.d.ts.map +1 -1
  51. package/dist/esm/config-rendering.js +15 -14
  52. package/dist/esm/config-rendering.js.map +1 -1
  53. package/dist/esm/helpers/vault/client-side.d.ts.map +1 -1
  54. package/dist/esm/helpers/vault/client-side.js.map +1 -1
  55. package/dist/esm/helpers/vault/server-side.d.ts.map +1 -1
  56. package/dist/esm/helpers/vault/server-side.js.map +1 -1
  57. package/dist/esm/hexclave-config-file.d.ts +15 -0
  58. package/dist/esm/hexclave-config-file.d.ts.map +1 -0
  59. package/dist/esm/{stack-config-file.js → hexclave-config-file.js} +7 -7
  60. package/dist/esm/hexclave-config-file.js.map +1 -0
  61. package/dist/esm/hooks/use-async-callback.js +1 -1
  62. package/dist/esm/hooks/use-async-external-store.js +1 -1
  63. package/dist/esm/hooks/use-strict-memo.js +1 -1
  64. package/dist/esm/interface/admin-metrics.d.ts +4 -4
  65. package/dist/esm/interface/admin-metrics.js.map +1 -1
  66. package/dist/esm/interface/client-interface.js +2 -2
  67. package/dist/esm/interface/client-interface.js.map +1 -1
  68. package/dist/esm/interface/conversations.d.ts +13 -13
  69. package/dist/esm/interface/crud/current-user.d.ts +9 -9
  70. package/dist/esm/interface/crud/email-outbox.d.ts +112 -112
  71. package/dist/esm/interface/crud/products.d.ts +1 -1
  72. package/dist/esm/interface/crud/project-api-keys.d.ts +2 -2
  73. package/dist/esm/interface/crud/project-permissions.js +5 -5
  74. package/dist/esm/interface/crud/project-permissions.js.map +1 -1
  75. package/dist/esm/interface/crud/projects.d.ts +28 -28
  76. package/dist/esm/interface/crud/team-member-profiles.d.ts +22 -22
  77. package/dist/esm/interface/crud/team-permissions.js +5 -5
  78. package/dist/esm/interface/crud/team-permissions.js.map +1 -1
  79. package/dist/esm/interface/crud/users.d.ts +14 -14
  80. package/dist/esm/interface/page-component-versions.js +107 -107
  81. package/dist/esm/interface/page-component-versions.js.map +1 -1
  82. package/dist/esm/interface/webhooks.d.ts +4 -4
  83. package/dist/esm/known-errors.js +4 -4
  84. package/dist/esm/known-errors.js.map +1 -1
  85. package/dist/esm/schema-fields.d.ts +15 -5
  86. package/dist/esm/schema-fields.d.ts.map +1 -1
  87. package/dist/esm/schema-fields.js +26 -16
  88. package/dist/esm/schema-fields.js.map +1 -1
  89. package/dist/esm/utils/crypto.d.ts.map +1 -1
  90. package/dist/esm/utils/crypto.js.map +1 -1
  91. package/dist/esm/utils/currency-constants.d.ts +6 -0
  92. package/dist/esm/utils/currency-constants.d.ts.map +1 -1
  93. package/dist/esm/utils/currency-constants.js.map +1 -1
  94. package/dist/esm/utils/dev-env-state-path.d.ts +3 -3
  95. package/dist/esm/utils/dev-env-state-path.d.ts.map +1 -1
  96. package/dist/esm/utils/dev-env-state-path.js +4 -4
  97. package/dist/esm/utils/dev-env-state-path.js.map +1 -1
  98. package/dist/esm/utils/errors.js +2 -2
  99. package/dist/esm/utils/errors.js.map +1 -1
  100. package/dist/esm/utils/esbuild.d.ts.map +1 -1
  101. package/dist/esm/utils/esbuild.js +0 -1
  102. package/dist/esm/utils/esbuild.js.map +1 -1
  103. package/dist/esm/utils/featurebase.d.ts +3 -3
  104. package/dist/esm/utils/featurebase.d.ts.map +1 -1
  105. package/dist/esm/utils/featurebase.js +15 -15
  106. package/dist/esm/utils/featurebase.js.map +1 -1
  107. package/dist/esm/utils/fs.js +6 -6
  108. package/dist/esm/utils/fs.js.map +1 -1
  109. package/dist/esm/utils/globals.d.ts.map +1 -1
  110. package/dist/esm/utils/globals.js +10 -10
  111. package/dist/esm/utils/globals.js.map +1 -1
  112. package/dist/esm/utils/jwt.d.ts.map +1 -1
  113. package/dist/esm/utils/jwt.js +3 -3
  114. package/dist/esm/utils/jwt.js.map +1 -1
  115. package/dist/esm/utils/redirect-urls.d.ts +3 -3
  116. package/dist/esm/utils/redirect-urls.d.ts.map +1 -1
  117. package/dist/esm/utils/redirect-urls.js +5 -5
  118. package/dist/esm/utils/redirect-urls.js.map +1 -1
  119. package/dist/esm/utils/urls.js.map +1 -1
  120. package/dist/helpers/vault/client-side.d.ts.map +1 -1
  121. package/dist/helpers/vault/client-side.js.map +1 -1
  122. package/dist/helpers/vault/server-side.d.ts.map +1 -1
  123. package/dist/helpers/vault/server-side.js.map +1 -1
  124. package/dist/hexclave-config-file.d.ts +15 -0
  125. package/dist/hexclave-config-file.d.ts.map +1 -0
  126. package/dist/{stack-config-file.js → hexclave-config-file.js} +8 -8
  127. package/dist/hexclave-config-file.js.map +1 -0
  128. package/dist/hooks/use-async-callback.js +1 -1
  129. package/dist/hooks/use-async-external-store.js +1 -1
  130. package/dist/hooks/use-strict-memo.js +1 -1
  131. package/dist/interface/admin-metrics.d.ts +4 -4
  132. package/dist/interface/admin-metrics.js.map +1 -1
  133. package/dist/interface/client-interface.js +2 -2
  134. package/dist/interface/client-interface.js.map +1 -1
  135. package/dist/interface/conversations.d.ts +13 -13
  136. package/dist/interface/crud/current-user.d.ts +9 -9
  137. package/dist/interface/crud/email-outbox.d.ts +112 -112
  138. package/dist/interface/crud/products.d.ts +1 -1
  139. package/dist/interface/crud/project-api-keys.d.ts +2 -2
  140. package/dist/interface/crud/project-permissions.js +5 -5
  141. package/dist/interface/crud/project-permissions.js.map +1 -1
  142. package/dist/interface/crud/projects.d.ts +28 -28
  143. package/dist/interface/crud/team-member-profiles.d.ts +22 -22
  144. package/dist/interface/crud/team-permissions.js +5 -5
  145. package/dist/interface/crud/team-permissions.js.map +1 -1
  146. package/dist/interface/crud/users.d.ts +14 -14
  147. package/dist/interface/page-component-versions.js +107 -107
  148. package/dist/interface/page-component-versions.js.map +1 -1
  149. package/dist/interface/webhooks.d.ts +4 -4
  150. package/dist/known-errors.js +4 -4
  151. package/dist/known-errors.js.map +1 -1
  152. package/dist/schema-fields.d.ts +15 -5
  153. package/dist/schema-fields.d.ts.map +1 -1
  154. package/dist/schema-fields.js +26 -16
  155. package/dist/schema-fields.js.map +1 -1
  156. package/dist/utils/crypto.d.ts.map +1 -1
  157. package/dist/utils/crypto.js.map +1 -1
  158. package/dist/utils/currency-constants.d.ts +6 -0
  159. package/dist/utils/currency-constants.d.ts.map +1 -1
  160. package/dist/utils/currency-constants.js.map +1 -1
  161. package/dist/utils/dev-env-state-path.d.ts +3 -3
  162. package/dist/utils/dev-env-state-path.d.ts.map +1 -1
  163. package/dist/utils/dev-env-state-path.js +5 -5
  164. package/dist/utils/dev-env-state-path.js.map +1 -1
  165. package/dist/utils/errors.js +2 -2
  166. package/dist/utils/errors.js.map +1 -1
  167. package/dist/utils/esbuild.d.ts.map +1 -1
  168. package/dist/utils/esbuild.js +0 -1
  169. package/dist/utils/esbuild.js.map +1 -1
  170. package/dist/utils/featurebase.d.ts +3 -3
  171. package/dist/utils/featurebase.d.ts.map +1 -1
  172. package/dist/utils/featurebase.js +15 -15
  173. package/dist/utils/featurebase.js.map +1 -1
  174. package/dist/utils/fs.js.map +1 -1
  175. package/dist/utils/globals.d.ts.map +1 -1
  176. package/dist/utils/globals.js +10 -10
  177. package/dist/utils/globals.js.map +1 -1
  178. package/dist/utils/jwt.d.ts.map +1 -1
  179. package/dist/utils/jwt.js +3 -3
  180. package/dist/utils/jwt.js.map +1 -1
  181. package/dist/utils/redirect-urls.d.ts +3 -3
  182. package/dist/utils/redirect-urls.d.ts.map +1 -1
  183. package/dist/utils/redirect-urls.js +5 -5
  184. package/dist/utils/redirect-urls.js.map +1 -1
  185. package/dist/utils/urls.js.map +1 -1
  186. package/package.json +2 -1
  187. package/src/ai/image-limits.ts +62 -0
  188. package/src/ai/llms/llms.ts +36 -0
  189. package/src/ai/unified-prompts/reminders.ts +27 -0
  190. package/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts +1047 -0
  191. package/src/ai/unified-prompts/skill-site-prompt-parts/brain.ts +5 -0
  192. package/src/ai/unified-prompts/skill-site-prompt-parts/cli-help.ts +5 -0
  193. package/src/ai/unified-prompts/skill-site-prompt-parts/config-docs.ts +5 -0
  194. package/src/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.ts +5 -0
  195. package/src/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.ts +5 -0
  196. package/src/ai/unified-prompts/skill-site-prompt-parts/docs-index.ts +80 -0
  197. package/src/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.ts +322 -0
  198. package/src/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.ts +5 -0
  199. package/src/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.ts +5 -0
  200. package/src/ai/unified-prompts/skill-site-prompt.ts +72 -0
  201. package/src/apps/apps-config.ts +177 -0
  202. package/src/apps/apps-ui.tsx +112 -0
  203. package/src/config/README.md +154 -0
  204. package/src/config/db-sync-mappings.ts +2293 -0
  205. package/src/config/format.ts +388 -0
  206. package/src/config/migrate-catalogs-to-product-lines.ts +475 -0
  207. package/src/config/schema-fuzzer.test.ts +377 -0
  208. package/src/config/schema.ts +1507 -0
  209. package/src/config-authoring.test.ts +52 -0
  210. package/src/config-authoring.ts +37 -0
  211. package/src/config-rendering.ts +142 -0
  212. package/src/crud.tsx +275 -0
  213. package/src/global.d.ts +1 -0
  214. package/src/helpers/emails.ts +250 -0
  215. package/src/helpers/init-prompt.ts +39 -0
  216. package/src/helpers/password.ts +16 -0
  217. package/src/helpers/production-mode.ts +58 -0
  218. package/src/helpers/support-sla.test.ts +124 -0
  219. package/src/helpers/support-sla.ts +93 -0
  220. package/src/helpers/vault/client-side.ts +92 -0
  221. package/src/helpers/vault/server-side.ts +153 -0
  222. package/src/hexclave-config-file.ts +120 -0
  223. package/src/hooks/use-async-callback.tsx +43 -0
  224. package/src/hooks/use-async-external-store.tsx +24 -0
  225. package/src/hooks/use-hash.tsx +14 -0
  226. package/src/hooks/use-hover.tsx +88 -0
  227. package/src/hooks/use-strict-memo.tsx +157 -0
  228. package/src/index.ts +17 -0
  229. package/src/interface/admin-interface.ts +1043 -0
  230. package/src/interface/admin-metrics.ts +214 -0
  231. package/src/interface/client-interface.test.ts +765 -0
  232. package/src/interface/client-interface.ts +2586 -0
  233. package/src/interface/conversations.ts +109 -0
  234. package/src/interface/crud/analytics.ts +11 -0
  235. package/src/interface/crud/connected-accounts.ts +52 -0
  236. package/src/interface/crud/contact-channels.ts +74 -0
  237. package/src/interface/crud/current-user.ts +72 -0
  238. package/src/interface/crud/email-outbox.ts +263 -0
  239. package/src/interface/crud/email-templates.ts +50 -0
  240. package/src/interface/crud/emails.ts +22 -0
  241. package/src/interface/crud/internal-api-keys.ts +69 -0
  242. package/src/interface/crud/invoices.ts +36 -0
  243. package/src/interface/crud/items.ts +24 -0
  244. package/src/interface/crud/notification-preferences.ts +33 -0
  245. package/src/interface/crud/oauth-providers.ts +91 -0
  246. package/src/interface/crud/products.ts +42 -0
  247. package/src/interface/crud/project-api-keys.ts +100 -0
  248. package/src/interface/crud/project-permissions.ts +118 -0
  249. package/src/interface/crud/projects.ts +229 -0
  250. package/src/interface/crud/session-replays.ts +85 -0
  251. package/src/interface/crud/sessions.ts +66 -0
  252. package/src/interface/crud/sign-up-rules.ts +12 -0
  253. package/src/interface/crud/svix-token.ts +20 -0
  254. package/src/interface/crud/team-invitation-details.ts +22 -0
  255. package/src/interface/crud/team-invitation.ts +35 -0
  256. package/src/interface/crud/team-member-profiles.ts +61 -0
  257. package/src/interface/crud/team-memberships.ts +56 -0
  258. package/src/interface/crud/team-permissions.ts +119 -0
  259. package/src/interface/crud/teams.ts +142 -0
  260. package/src/interface/crud/transactions.ts +131 -0
  261. package/src/interface/crud/users.ts +185 -0
  262. package/src/interface/handler-urls.ts +74 -0
  263. package/src/interface/page-component-versions.ts +1702 -0
  264. package/src/interface/server-interface.ts +1146 -0
  265. package/src/interface/webhooks.ts +28 -0
  266. package/src/known-errors.tsx +2031 -0
  267. package/src/local-emulator.ts +5 -0
  268. package/src/payments/payment-methods.ts +167 -0
  269. package/src/payments/stripe-limits.ts +18 -0
  270. package/src/plans.ts +107 -0
  271. package/src/schema-fields.ts +944 -0
  272. package/src/sessions.ts +310 -0
  273. package/src/utils/api-keys.tsx +122 -0
  274. package/src/utils/arrays.tsx +248 -0
  275. package/src/utils/auth-methods.ts +8 -0
  276. package/src/utils/base64.tsx +24 -0
  277. package/src/utils/booleans.tsx +34 -0
  278. package/src/utils/browser-compat.tsx +17 -0
  279. package/src/utils/bytes.tsx +280 -0
  280. package/src/utils/caches.tsx +280 -0
  281. package/src/utils/cel-fields.ts +92 -0
  282. package/src/utils/cloud-hosts.tsx +92 -0
  283. package/src/utils/compile-time.tsx +11 -0
  284. package/src/utils/country-codes.ts +39 -0
  285. package/src/utils/crypto.tsx +174 -0
  286. package/src/utils/currencies.tsx +53 -0
  287. package/src/utils/currency-constants.tsx +51 -0
  288. package/src/utils/dates.tsx +246 -0
  289. package/src/utils/dev-env-state-path.ts +14 -0
  290. package/src/utils/dom.tsx +7 -0
  291. package/src/utils/env.tsx +117 -0
  292. package/src/utils/errors.tsx +284 -0
  293. package/src/utils/esbuild.tsx +235 -0
  294. package/src/utils/featurebase.tsx +247 -0
  295. package/src/utils/fs.tsx +33 -0
  296. package/src/utils/functions.tsx +22 -0
  297. package/src/utils/geo.tsx +16 -0
  298. package/src/utils/globals.tsx +48 -0
  299. package/src/utils/hashes.tsx +52 -0
  300. package/src/utils/html.tsx +60 -0
  301. package/src/utils/http.tsx +91 -0
  302. package/src/utils/ips.tsx +47 -0
  303. package/src/utils/json.tsx +200 -0
  304. package/src/utils/jsx-editable-transpiler.test.ts +156 -0
  305. package/src/utils/jsx-editable-transpiler.tsx +401 -0
  306. package/src/utils/jwt.tsx +170 -0
  307. package/src/utils/locks.tsx +71 -0
  308. package/src/utils/maps.tsx +407 -0
  309. package/src/utils/math.tsx +18 -0
  310. package/src/utils/monkey-patch.tsx +29 -0
  311. package/src/utils/node-http.tsx +47 -0
  312. package/src/utils/numbers.tsx +82 -0
  313. package/src/utils/oauth.tsx +9 -0
  314. package/src/utils/objects.tsx +581 -0
  315. package/src/utils/paginated-lists.test.ts +1039 -0
  316. package/src/utils/paginated-lists.tsx +479 -0
  317. package/src/utils/passkey.tsx +1 -0
  318. package/src/utils/promises.tsx +540 -0
  319. package/src/utils/proxies.tsx +212 -0
  320. package/src/utils/react.tsx +308 -0
  321. package/src/utils/redirect-urls.tsx +299 -0
  322. package/src/utils/regex.tsx +10 -0
  323. package/src/utils/results.tsx +411 -0
  324. package/src/utils/sentry.tsx +20 -0
  325. package/src/utils/stores.tsx +238 -0
  326. package/src/utils/strings.nicify.test.ts +253 -0
  327. package/src/utils/strings.tsx +723 -0
  328. package/src/utils/telemetry.tsx +37 -0
  329. package/src/utils/turnstile-browser.ts +106 -0
  330. package/src/utils/turnstile-flow.test.ts +101 -0
  331. package/src/utils/turnstile-flow.ts +266 -0
  332. package/src/utils/turnstile.ts +34 -0
  333. package/src/utils/typed-arrays.tsx +17 -0
  334. package/src/utils/types.tsx +208 -0
  335. package/src/utils/unicode.tsx +24 -0
  336. package/src/utils/urls.tsx +411 -0
  337. package/src/utils/uuids.tsx +47 -0
  338. package/dist/esm/stack-config-file.d.ts +0 -15
  339. package/dist/esm/stack-config-file.d.ts.map +0 -1
  340. package/dist/esm/stack-config-file.js.map +0 -1
  341. package/dist/stack-config-file.d.ts +0 -15
  342. package/dist/stack-config-file.d.ts.map +0 -1
  343. package/dist/stack-config-file.js.map +0 -1
@@ -0,0 +1,407 @@
1
+ import { Result } from "./results";
2
+
3
+ export class WeakRefIfAvailable<T extends object> {
4
+ private readonly _ref: { deref: () => T | undefined };
5
+
6
+ constructor(value: T) {
7
+ if (typeof WeakRef === "undefined") {
8
+ this._ref = { deref: () => value };
9
+ } else {
10
+ this._ref = new WeakRef<T>(value);
11
+ }
12
+ }
13
+
14
+ deref(): T | undefined {
15
+ return this._ref.deref();
16
+ }
17
+ }
18
+ import.meta.vitest?.test("WeakRefIfAvailable", ({ expect }) => {
19
+ // Test with an object
20
+ const obj = { id: 1, name: "test" };
21
+ const weakRef = new WeakRefIfAvailable(obj);
22
+
23
+ // Test deref returns the original object
24
+ expect(weakRef.deref()).toBe(obj);
25
+
26
+ // Test with a different object
27
+ const obj2 = { id: 2, name: "test2" };
28
+ const weakRef2 = new WeakRefIfAvailable(obj2);
29
+ expect(weakRef2.deref()).toBe(obj2);
30
+ expect(weakRef2.deref()).not.toBe(obj);
31
+
32
+ // We can't easily test garbage collection in this environment,
33
+ // but we can verify the basic functionality works
34
+ });
35
+
36
+
37
+ /**
38
+ * A WeakMap-like object that can be iterated over.
39
+ *
40
+ * Note that it relies on WeakRef, and always falls back to the regular Map behavior (ie. no GC) in browsers that don't support it.
41
+ */
42
+ export class IterableWeakMap<K extends object, V> {
43
+ private readonly _weakMap: WeakMap<K & WeakKey, { value: V, keyRef: WeakRefIfAvailable<K & WeakKey> }>;
44
+ private readonly _keyRefs: Set<WeakRefIfAvailable<K & WeakKey>>;
45
+
46
+ constructor(entries?: readonly (readonly [K, V])[] | null) {
47
+ const mappedEntries = entries?.map((e) => [e[0], { value: e[1], keyRef: new WeakRefIfAvailable(e[0]) }] as const);
48
+ this._weakMap = new WeakMap(mappedEntries ?? []);
49
+ this._keyRefs = new Set(mappedEntries?.map((e) => e[1].keyRef) ?? []);
50
+ }
51
+
52
+ get(key: K): V | undefined {
53
+ return this._weakMap.get(key)?.value;
54
+ }
55
+
56
+ set(key: K, value: V): this {
57
+ const existing = this._weakMap.get(key);
58
+ const updated = { value, keyRef: existing?.keyRef ?? new WeakRefIfAvailable(key) };
59
+ this._weakMap.set(key, updated);
60
+ this._keyRefs.add(updated.keyRef);
61
+ return this;
62
+ }
63
+
64
+ delete(key: K): boolean {
65
+ const res = this._weakMap.get(key);
66
+ if (res) {
67
+ this._weakMap.delete(key);
68
+ this._keyRefs.delete(res.keyRef);
69
+ return true;
70
+ }
71
+ return false;
72
+ }
73
+
74
+ has(key: K): boolean {
75
+ return this._weakMap.has(key) && this._keyRefs.has(this._weakMap.get(key)!.keyRef);
76
+ }
77
+
78
+ *[Symbol.iterator](): IterableIterator<[K, V]> {
79
+ for (const keyRef of this._keyRefs) {
80
+ const key = keyRef.deref();
81
+ const existing = key ? this._weakMap.get(key) : undefined;
82
+ if (!key) {
83
+ // This can happen if the key was GCed. Remove it so the next iteration is faster.
84
+ this._keyRefs.delete(keyRef);
85
+ } else if (existing) {
86
+ yield [key, existing.value];
87
+ }
88
+ }
89
+ }
90
+
91
+ [Symbol.toStringTag] = "IterableWeakMap";
92
+ }
93
+ import.meta.vitest?.test("IterableWeakMap", ({ expect }) => {
94
+ // Test basic functionality
95
+ const map = new IterableWeakMap<{ id: number }, string>();
96
+
97
+ // Create object keys
98
+ const obj1 = { id: 1 };
99
+ const obj2 = { id: 2 };
100
+
101
+ // Test set and get
102
+ map.set(obj1, "value1");
103
+ expect(map.get(obj1)).toBe("value1");
104
+
105
+ // Test has
106
+ expect(map.has(obj1)).toBe(true);
107
+ expect(map.has(obj2)).toBe(false);
108
+ expect(map.has({ id: 1 })).toBe(false); // Different object with same content
109
+
110
+ // Test with multiple keys
111
+ map.set(obj2, "value2");
112
+ expect(map.get(obj2)).toBe("value2");
113
+ expect(map.get(obj1)).toBe("value1"); // Original still exists
114
+
115
+ // Test delete
116
+ expect(map.delete(obj1)).toBe(true);
117
+ expect(map.has(obj1)).toBe(false);
118
+ expect(map.get(obj1)).toBeUndefined();
119
+ expect(map.has(obj2)).toBe(true); // Other key still exists
120
+
121
+ // Test delete non-existent key
122
+ expect(map.delete({ id: 3 })).toBe(false);
123
+
124
+ // Test iteration
125
+ const iterMap = new IterableWeakMap<{ id: number }, number>();
126
+ const iterObj1 = { id: 1 };
127
+ const iterObj2 = { id: 2 };
128
+ const iterObj3 = { id: 3 };
129
+
130
+ iterMap.set(iterObj1, 1);
131
+ iterMap.set(iterObj2, 2);
132
+ iterMap.set(iterObj3, 3);
133
+
134
+ const entries = Array.from(iterMap);
135
+ expect(entries.length).toBe(3);
136
+
137
+ // Find entries by their values since we can't directly compare objects in the array
138
+ const values = entries.map(entry => entry[1]);
139
+ expect(values).toContain(1);
140
+ expect(values).toContain(2);
141
+ expect(values).toContain(3);
142
+
143
+ // Test constructor with entries
144
+ const initialEntries: [{ id: number }, string][] = [
145
+ [{ id: 4 }, "initial1"],
146
+ [{ id: 5 }, "initial2"]
147
+ ];
148
+ const mapWithEntries = new IterableWeakMap(initialEntries);
149
+
150
+ // We can't directly access the initial entries since they're different object references
151
+ // But we can verify the map has the correct number of entries
152
+ const entriesFromConstructor = Array.from(mapWithEntries);
153
+ expect(entriesFromConstructor.length).toBe(2);
154
+ });
155
+
156
+ /**
157
+ * A map that is a IterableWeakMap for object keys and a regular Map for primitive keys. Also provides iteration over both
158
+ * object and primitive keys.
159
+ *
160
+ * Note that, just like IterableWeakMap, older browsers without support for WeakRef will use a regular Map for object keys.
161
+ */
162
+ export class MaybeWeakMap<K, V> {
163
+ private readonly _primitiveMap: Map<K, V>;
164
+ private readonly _weakMap: IterableWeakMap<K & WeakKey, V>;
165
+
166
+ constructor(entries?: readonly (readonly [K, V])[] | null) {
167
+ const entriesArray = [...entries ?? []];
168
+ this._primitiveMap = new Map(entriesArray.filter((e) => !this._isAllowedInWeakMap(e[0])));
169
+ this._weakMap = new IterableWeakMap(entriesArray.filter((e): e is [K & WeakKey, V] => this._isAllowedInWeakMap(e[0])));
170
+ }
171
+
172
+ private _isAllowedInWeakMap(key: K): key is K & WeakKey {
173
+ return (typeof key === "object" && key !== null) || (typeof key === "symbol" && Symbol.keyFor(key) === undefined);
174
+ }
175
+
176
+ get(key: K): V | undefined {
177
+ if (this._isAllowedInWeakMap(key)) {
178
+ return this._weakMap.get(key);
179
+ } else {
180
+ return this._primitiveMap.get(key);
181
+ }
182
+ }
183
+
184
+ set(key: K, value: V): this {
185
+ if (this._isAllowedInWeakMap(key)) {
186
+ this._weakMap.set(key, value);
187
+ } else {
188
+ this._primitiveMap.set(key, value);
189
+ }
190
+ return this;
191
+ }
192
+
193
+ delete(key: K): boolean {
194
+ if (this._isAllowedInWeakMap(key)) {
195
+ return this._weakMap.delete(key);
196
+ } else {
197
+ return this._primitiveMap.delete(key);
198
+ }
199
+ }
200
+
201
+ has(key: K): boolean {
202
+ if (this._isAllowedInWeakMap(key)) {
203
+ return this._weakMap.has(key);
204
+ } else {
205
+ return this._primitiveMap.has(key);
206
+ }
207
+ }
208
+
209
+ *[Symbol.iterator](): IterableIterator<[K, V]> {
210
+ yield* this._primitiveMap;
211
+ yield* this._weakMap;
212
+ }
213
+
214
+ [Symbol.toStringTag] = "MaybeWeakMap";
215
+ }
216
+ import.meta.vitest?.test("MaybeWeakMap", ({ expect }) => {
217
+ // Test with primitive keys
218
+ const map = new MaybeWeakMap<string | object, number>();
219
+
220
+ // Test with string keys
221
+ map.set("key1", 1);
222
+ map.set("key2", 2);
223
+ expect(map.get("key1")).toBe(1);
224
+ expect(map.get("key2")).toBe(2);
225
+ expect(map.has("key1")).toBe(true);
226
+ expect(map.has("nonexistent")).toBe(false);
227
+
228
+ // Test with object keys
229
+ const obj1 = { id: 1 };
230
+ const obj2 = { id: 2 };
231
+ map.set(obj1, 3);
232
+ map.set(obj2, 4);
233
+ expect(map.get(obj1)).toBe(3);
234
+ expect(map.get(obj2)).toBe(4);
235
+ expect(map.has(obj1)).toBe(true);
236
+
237
+ // Test delete with primitive key
238
+ expect(map.delete("key1")).toBe(true);
239
+ expect(map.has("key1")).toBe(false);
240
+ expect(map.delete("nonexistent")).toBe(false);
241
+
242
+ // Test delete with object key
243
+ expect(map.delete(obj1)).toBe(true);
244
+ expect(map.has(obj1)).toBe(false);
245
+
246
+ // Test iteration
247
+ const entries = Array.from(map);
248
+ expect(entries.length).toBe(2);
249
+ expect(entries).toContainEqual(["key2", 2]);
250
+ expect(entries).toContainEqual([obj2, 4]);
251
+
252
+ // Test constructor with entries
253
+ const initialEntries: [string | object, number][] = [
254
+ ["initial1", 10],
255
+ [{ id: 3 }, 20]
256
+ ];
257
+ const mapWithEntries = new MaybeWeakMap(initialEntries);
258
+ expect(mapWithEntries.get("initial1")).toBe(10);
259
+ expect(mapWithEntries.get(initialEntries[1][0])).toBe(20);
260
+ });
261
+
262
+
263
+ type DependenciesMapInner<V> = (
264
+ & { map: MaybeWeakMap<unknown, DependenciesMapInner<V>> }
265
+ & (
266
+ | { hasValue: true, value: V }
267
+ | { hasValue: false, value: undefined }
268
+ )
269
+ );
270
+
271
+ /**
272
+ * A map that stores values indexed by an array of keys. If the keys are objects and the environment supports WeakRefs,
273
+ * they are stored in a WeakMap.
274
+ */
275
+ export class DependenciesMap<K extends any[], V> {
276
+ private _inner: DependenciesMapInner<V> = { map: new MaybeWeakMap(), hasValue: false, value: undefined };
277
+
278
+ private _valueToResult(inner: DependenciesMapInner<V>): Result<V, void> {
279
+ if (inner.hasValue) {
280
+ return Result.ok(inner.value);
281
+ } else {
282
+ return Result.error(undefined);
283
+ }
284
+ }
285
+
286
+
287
+ private _unwrapFromInner(dependencies: any[], inner: DependenciesMapInner<V>): Result<V, void> {
288
+ if ((dependencies.length === 0)) {
289
+ return this._valueToResult(inner);
290
+ } else {
291
+ const [key, ...rest] = dependencies;
292
+ const newInner = inner.map.get(key);
293
+ if (!newInner) {
294
+ return Result.error(undefined);
295
+ }
296
+ return this._unwrapFromInner(rest, newInner);
297
+ }
298
+ }
299
+
300
+ private _setInInner(dependencies: any[], value: Result<V, void>, inner: DependenciesMapInner<V>): Result<V, void> {
301
+ if (dependencies.length === 0) {
302
+ const res = this._valueToResult(inner);
303
+ if (value.status === "ok") {
304
+ inner.hasValue = true;
305
+ inner.value = value.data;
306
+ } else {
307
+ inner.hasValue = false;
308
+ inner.value = undefined;
309
+ }
310
+ return res;
311
+ } else {
312
+ const [key, ...rest] = dependencies;
313
+ let newInner = inner.map.get(key);
314
+ if (!newInner) {
315
+ inner.map.set(key, newInner = { map: new MaybeWeakMap(), hasValue: false, value: undefined });
316
+ }
317
+ return this._setInInner(rest, value, newInner);
318
+ }
319
+ }
320
+
321
+ private *_iterateInner(dependencies: any[], inner: DependenciesMapInner<V>): IterableIterator<[K, V]> {
322
+ if (inner.hasValue) {
323
+ yield [dependencies as K, inner.value];
324
+ }
325
+ for (const [key, value] of inner.map) {
326
+ yield* this._iterateInner([...dependencies, key], value);
327
+ }
328
+ }
329
+
330
+ get(dependencies: K): V | undefined {
331
+ return Result.or(this._unwrapFromInner(dependencies, this._inner), undefined);
332
+ }
333
+
334
+ set(dependencies: K, value: V): this {
335
+ this._setInInner(dependencies, Result.ok(value), this._inner);
336
+ return this;
337
+ }
338
+
339
+ delete(dependencies: K): boolean {
340
+ return this._setInInner(dependencies, Result.error(undefined), this._inner).status === "ok";
341
+ }
342
+
343
+ has(dependencies: K): boolean {
344
+ return this._unwrapFromInner(dependencies, this._inner).status === "ok";
345
+ }
346
+
347
+ clear(): void {
348
+ this._inner = { map: new MaybeWeakMap(), hasValue: false, value: undefined };
349
+ }
350
+
351
+ *[Symbol.iterator](): IterableIterator<[K, V]> {
352
+ yield* this._iterateInner([], this._inner);
353
+ }
354
+
355
+ [Symbol.toStringTag] = "DependenciesMap";
356
+ }
357
+ import.meta.vitest?.test("DependenciesMap", ({ expect }) => {
358
+ // Test basic functionality
359
+ const map = new DependenciesMap<[string, number], string>();
360
+
361
+ // Test set and get
362
+ map.set(["key", 1], "value1");
363
+ expect(map.get(["key", 1])).toBe("value1");
364
+
365
+ // Test has
366
+ expect(map.has(["key", 1])).toBe(true);
367
+ expect(map.has(["key", 2])).toBe(false);
368
+
369
+ // Test with different dependencies
370
+ map.set(["key", 2], "value2");
371
+ expect(map.get(["key", 2])).toBe("value2");
372
+ expect(map.get(["key", 1])).toBe("value1"); // Original still exists
373
+
374
+ // Test delete
375
+ expect(map.delete(["key", 1])).toBe(true);
376
+ expect(map.has(["key", 1])).toBe(false);
377
+ expect(map.get(["key", 1])).toBeUndefined();
378
+ expect(map.has(["key", 2])).toBe(true); // Other key still exists
379
+
380
+ // Test delete non-existent key
381
+ expect(map.delete(["nonexistent", 1])).toBe(false);
382
+
383
+ // Test clear
384
+ map.clear();
385
+ expect(map.has(["key", 2])).toBe(false);
386
+
387
+ // Test with object keys
388
+ const objMap = new DependenciesMap<[object, number], string>();
389
+ const obj1 = { id: 1 };
390
+ const obj2 = { id: 2 };
391
+ objMap.set([obj1, 1], "object1");
392
+ objMap.set([obj2, 2], "object2");
393
+ expect(objMap.get([obj1, 1])).toBe("object1");
394
+ expect(objMap.get([obj2, 2])).toBe("object2");
395
+
396
+ // Test iteration
397
+ const iterMap = new DependenciesMap<[string], number>();
398
+ iterMap.set(["a"], 1);
399
+ iterMap.set(["b"], 2);
400
+ iterMap.set(["c"], 3);
401
+
402
+ const entries = Array.from(iterMap);
403
+ expect(entries.length).toBe(3);
404
+ expect(entries).toContainEqual([["a"], 1]);
405
+ expect(entries).toContainEqual([["b"], 2]);
406
+ expect(entries).toContainEqual([["c"], 3]);
407
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Similar to the modulo operator, but always returns a positive number (even when the input is negative).
3
+ */
4
+ export function remainder(n: number, d: number): number {
5
+ return ((n % d) + Math.abs(d)) % d;
6
+ }
7
+ import.meta.vitest?.test("remainder", ({ expect }) => {
8
+ expect(remainder(10, 3)).toBe(1);
9
+ expect(remainder(10, 5)).toBe(0);
10
+ expect(remainder(10, 7)).toBe(3);
11
+ // Test with negative numbers
12
+ expect(remainder(-10, 3)).toBe(2);
13
+ expect(remainder(-5, 2)).toBe(1);
14
+ expect(remainder(-7, 4)).toBe(1);
15
+ // Test with decimal numbers
16
+ expect(remainder(10.5, 3)).toBeCloseTo(1.5);
17
+ expect(remainder(-10.5, 3)).toBeCloseTo(1.5);
18
+ });
@@ -0,0 +1,29 @@
1
+ import { createGlobal } from "./globals";
2
+
3
+ export const NO_SUSPENSE_BOUNDARY_ERROR_SENTINEL = "__stack-no-suspense-boundary-error__";
4
+
5
+ export function isNoSuspenseBoundaryError(value: unknown): boolean {
6
+ return (
7
+ typeof value === "object"
8
+ && value !== null
9
+ && (value as Record<string, unknown>).__noSuspenseBoundarySentinel === NO_SUSPENSE_BOUNDARY_ERROR_SENTINEL
10
+ );
11
+ }
12
+
13
+ export function ensureMonkeyPatch() {
14
+ createGlobal("__console-error-monkey-patch__", () => {
15
+ const originalConsoleError = console.error;
16
+ console.error = function (...args: unknown[]) {
17
+ // React's default error handlers will log all errors to the console, even those that we intentionally use to suppress SSR.
18
+ // Next.js among others override the default error handler and will not log SSR errors to the console.
19
+ // However, vanilla React and other frameworks like TanStack Start use the default error handler.
20
+ // Hence, we suppress the error here if it is a NoSuspenseBoundaryError.
21
+ // It's very cursed, but it's really our best option. Talk to @konsti if you want to know more.
22
+ if (args.length === 1 && isNoSuspenseBoundaryError(args[0])) {
23
+ return;
24
+ }
25
+ return originalConsoleError.apply(this, args);
26
+ };
27
+ return true;
28
+ });
29
+ }
@@ -0,0 +1,47 @@
1
+ import { IncomingMessage, ServerResponse } from "http";
2
+ import { getRelativePart } from "./urls";
3
+
4
+ class ServerResponseWithBodyChunks extends ServerResponse {
5
+ bodyChunks: Uint8Array[] = [];
6
+
7
+ // note: we actually override this, even though it's private in the parent
8
+ _send(data: string, encoding: BufferEncoding, callback?: (() => void) | null, byteLength?: number) {
9
+ if (typeof encoding === "function") {
10
+ callback = encoding;
11
+ encoding = "utf-8";
12
+ }
13
+ const encodedBuffer = new Uint8Array(Buffer.from(data, encoding));
14
+ this.bodyChunks.push(encodedBuffer);
15
+ callback?.();
16
+ }
17
+ }
18
+
19
+ export async function createNodeHttpServerDuplex(options: {
20
+ method: string,
21
+ originalUrl?: URL,
22
+ url: URL,
23
+ headers: Headers,
24
+ body: Uint8Array,
25
+ }): Promise<[IncomingMessage, ServerResponseWithBodyChunks]> {
26
+ // See https://github.com/nodejs/node/blob/main/lib/_http_incoming.js
27
+ // and https://github.com/nodejs/node/blob/main/lib/_http_common.js (particularly the `parserXyz` functions)
28
+
29
+ const incomingMessage = new IncomingMessage({
30
+ encrypted: options.originalUrl?.protocol === "https:", // trick frameworks into believing this is an HTTPS request
31
+ } as any);
32
+ incomingMessage.httpVersionMajor = 1;
33
+ incomingMessage.httpVersionMinor = 1;
34
+ incomingMessage.httpVersion = '1.1';
35
+ incomingMessage.method = options.method;
36
+ incomingMessage.url = getRelativePart(options.url);
37
+ (incomingMessage as any).originalUrl = options.originalUrl && getRelativePart(options.originalUrl); // originalUrl is an extension used by some servers; for example, oidc-provider reads it to construct the paths for the .well-known/openid-configuration
38
+ const rawHeaders = [...options.headers.entries()].flat();
39
+ (incomingMessage as any)._addHeaderLines(rawHeaders, rawHeaders.length);
40
+ incomingMessage.push(Buffer.from(options.body));
41
+ incomingMessage.complete = true;
42
+ incomingMessage.push(null); // to emit end event, see: https://github.com/nodejs/node/blob/4cf6fabce20eb3050c5b543d249e931ea3d3cad5/lib/_http_common.js#L150
43
+
44
+ const serverResponse = new ServerResponseWithBodyChunks(incomingMessage);
45
+
46
+ return [incomingMessage, serverResponse];
47
+ }
@@ -0,0 +1,82 @@
1
+ const magnitudes = [
2
+ [1_000, "k"],
3
+ [1_000, "M"],
4
+ [1_000, "bn"],
5
+ [1_000, "bln"],
6
+ [1_000, "trln"],
7
+ ] as const;
8
+
9
+ export function prettyPrintWithMagnitudes(num: number): string {
10
+ if (typeof num !== "number") throw new Error("Expected a number");
11
+ if (Number.isNaN(num)) return "NaN";
12
+ if (num < 0) return "-" + prettyPrintWithMagnitudes(-num);
13
+ if (!Number.isFinite(num)) return "∞";
14
+
15
+ let current = toFixedMax(num, 1);
16
+ let lastSuffix = "";
17
+ for (const [difference, suffix] of magnitudes) {
18
+ if (+current >= difference) {
19
+ current = toFixedMax(+current / difference, 1);
20
+ lastSuffix = suffix;
21
+ } else {
22
+ break;
23
+ }
24
+ }
25
+ return current + lastSuffix;
26
+ }
27
+ import.meta.vitest?.test("prettyPrintWithMagnitudes", ({ expect }) => {
28
+ // Test different magnitudes
29
+ expect(prettyPrintWithMagnitudes(999)).toBe("999");
30
+ expect(prettyPrintWithMagnitudes(1000)).toBe("1k");
31
+ expect(prettyPrintWithMagnitudes(1500)).toBe("1.5k");
32
+ expect(prettyPrintWithMagnitudes(999499)).toBe("999.5k");
33
+ expect(prettyPrintWithMagnitudes(999500)).toBe("999.5k");
34
+ expect(prettyPrintWithMagnitudes(999949)).toBe("999.9k");
35
+ expect(prettyPrintWithMagnitudes(999950)).toBe("1M");
36
+ expect(prettyPrintWithMagnitudes(1000000)).toBe("1M");
37
+ expect(prettyPrintWithMagnitudes(1500000)).toBe("1.5M");
38
+ expect(prettyPrintWithMagnitudes(1000000000)).toBe("1bn");
39
+ expect(prettyPrintWithMagnitudes(1500000000)).toBe("1.5bn");
40
+ expect(prettyPrintWithMagnitudes(1000000000000)).toBe("1bln");
41
+ expect(prettyPrintWithMagnitudes(1500000000000)).toBe("1.5bln");
42
+ expect(prettyPrintWithMagnitudes(1000000000000000)).toBe("1trln");
43
+ expect(prettyPrintWithMagnitudes(1500000000000000)).toBe("1.5trln");
44
+ // Test small numbers
45
+ expect(prettyPrintWithMagnitudes(100)).toBe("100");
46
+ expect(prettyPrintWithMagnitudes(0)).toBe("0");
47
+ expect(prettyPrintWithMagnitudes(0.5)).toBe("0.5");
48
+ // Test negative numbers
49
+ expect(prettyPrintWithMagnitudes(-1000)).toBe("-1k");
50
+ expect(prettyPrintWithMagnitudes(-1500000)).toBe("-1.5M");
51
+ // Test special cases
52
+ expect(prettyPrintWithMagnitudes(NaN)).toBe("NaN");
53
+ expect(prettyPrintWithMagnitudes(Infinity)).toBe("∞");
54
+ expect(prettyPrintWithMagnitudes(-Infinity)).toBe("-∞");
55
+ });
56
+
57
+ export function toFixedMax(num: number, maxDecimals: number): string {
58
+ return num.toFixed(maxDecimals).replace(/\.?0+$/, "");
59
+ }
60
+ import.meta.vitest?.test("toFixedMax", ({ expect }) => {
61
+ expect(toFixedMax(1, 2)).toBe("1");
62
+ expect(toFixedMax(1.2, 2)).toBe("1.2");
63
+ expect(toFixedMax(1.23, 2)).toBe("1.23");
64
+ expect(toFixedMax(1.234, 2)).toBe("1.23");
65
+ expect(toFixedMax(1.0, 2)).toBe("1");
66
+ expect(toFixedMax(1.20, 2)).toBe("1.2");
67
+ expect(toFixedMax(0, 2)).toBe("0");
68
+ });
69
+
70
+ export function numberCompare(a: number, b: number): number {
71
+ return Math.sign(a - b);
72
+ }
73
+ import.meta.vitest?.test("numberCompare", ({ expect }) => {
74
+ expect(numberCompare(1, 2)).toBe(-1);
75
+ expect(numberCompare(2, 1)).toBe(1);
76
+ expect(numberCompare(1, 1)).toBe(0);
77
+ expect(numberCompare(0, 0)).toBe(0);
78
+ expect(numberCompare(-1, -2)).toBe(1);
79
+ expect(numberCompare(-2, -1)).toBe(-1);
80
+ expect(numberCompare(-1, 1)).toBe(-1);
81
+ expect(numberCompare(1, -1)).toBe(1);
82
+ });
@@ -0,0 +1,9 @@
1
+ export const standardProviders = ["google", "github", "microsoft", "spotify", "facebook", "discord", "gitlab", "bitbucket", "linkedin", "apple", "x", "twitch"] as const;
2
+ // No more shared providers should be added except for special cases
3
+ export const sharedProviders = ["google", "github", "microsoft", "spotify"] as const;
4
+ export const allProviders = standardProviders;
5
+ export const publishableClientKeyNotNecessarySentinel = "__stack_public_client__";
6
+
7
+ export type ProviderType = typeof allProviders[number];
8
+ export type StandardProviderType = typeof standardProviders[number];
9
+ export type SharedProviderType = typeof sharedProviders[number];