@molecule/app-solid 1.0.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 (107) hide show
  1. package/LICENSE +115 -0
  2. package/README.md +2543 -0
  3. package/dist/context.d.ts +82 -0
  4. package/dist/context.d.ts.map +1 -0
  5. package/dist/context.js +141 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/index.d.ts +61 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +61 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/primitives/async-state.d.ts +46 -0
  12. package/dist/primitives/async-state.d.ts.map +1 -0
  13. package/dist/primitives/async-state.js +83 -0
  14. package/dist/primitives/async-state.js.map +1 -0
  15. package/dist/primitives/auth.d.ts +85 -0
  16. package/dist/primitives/auth.d.ts.map +1 -0
  17. package/dist/primitives/auth.js +147 -0
  18. package/dist/primitives/auth.js.map +1 -0
  19. package/dist/primitives/capacitor-app.d.ts +46 -0
  20. package/dist/primitives/capacitor-app.d.ts.map +1 -0
  21. package/dist/primitives/capacitor-app.js +57 -0
  22. package/dist/primitives/capacitor-app.js.map +1 -0
  23. package/dist/primitives/change-password.d.ts +36 -0
  24. package/dist/primitives/change-password.d.ts.map +1 -0
  25. package/dist/primitives/change-password.js +32 -0
  26. package/dist/primitives/change-password.js.map +1 -0
  27. package/dist/primitives/device.d.ts +48 -0
  28. package/dist/primitives/device.d.ts.map +1 -0
  29. package/dist/primitives/device.js +47 -0
  30. package/dist/primitives/device.js.map +1 -0
  31. package/dist/primitives/forms.d.ts +193 -0
  32. package/dist/primitives/forms.d.ts.map +1 -0
  33. package/dist/primitives/forms.js +309 -0
  34. package/dist/primitives/forms.js.map +1 -0
  35. package/dist/primitives/http.d.ts +176 -0
  36. package/dist/primitives/http.d.ts.map +1 -0
  37. package/dist/primitives/http.js +254 -0
  38. package/dist/primitives/http.js.map +1 -0
  39. package/dist/primitives/i18n.d.ts +146 -0
  40. package/dist/primitives/i18n.d.ts.map +1 -0
  41. package/dist/primitives/i18n.js +223 -0
  42. package/dist/primitives/i18n.js.map +1 -0
  43. package/dist/primitives/index.d.ts +27 -0
  44. package/dist/primitives/index.d.ts.map +1 -0
  45. package/dist/primitives/index.js +27 -0
  46. package/dist/primitives/index.js.map +1 -0
  47. package/dist/primitives/logger.d.ts +143 -0
  48. package/dist/primitives/logger.d.ts.map +1 -0
  49. package/dist/primitives/logger.js +165 -0
  50. package/dist/primitives/logger.js.map +1 -0
  51. package/dist/primitives/login.d.ts +37 -0
  52. package/dist/primitives/login.d.ts.map +1 -0
  53. package/dist/primitives/login.js +32 -0
  54. package/dist/primitives/login.js.map +1 -0
  55. package/dist/primitives/oauth.d.ts +102 -0
  56. package/dist/primitives/oauth.d.ts.map +1 -0
  57. package/dist/primitives/oauth.js +232 -0
  58. package/dist/primitives/oauth.js.map +1 -0
  59. package/dist/primitives/password-reset.d.ts +46 -0
  60. package/dist/primitives/password-reset.d.ts.map +1 -0
  61. package/dist/primitives/password-reset.js +49 -0
  62. package/dist/primitives/password-reset.js.map +1 -0
  63. package/dist/primitives/platform.d.ts +48 -0
  64. package/dist/primitives/platform.d.ts.map +1 -0
  65. package/dist/primitives/platform.js +47 -0
  66. package/dist/primitives/platform.js.map +1 -0
  67. package/dist/primitives/promise.d.ts +46 -0
  68. package/dist/primitives/promise.d.ts.map +1 -0
  69. package/dist/primitives/promise.js +104 -0
  70. package/dist/primitives/promise.js.map +1 -0
  71. package/dist/primitives/push.d.ts +52 -0
  72. package/dist/primitives/push.d.ts.map +1 -0
  73. package/dist/primitives/push.js +72 -0
  74. package/dist/primitives/push.js.map +1 -0
  75. package/dist/primitives/router.d.ts +170 -0
  76. package/dist/primitives/router.d.ts.map +1 -0
  77. package/dist/primitives/router.js +251 -0
  78. package/dist/primitives/router.js.map +1 -0
  79. package/dist/primitives/signup.d.ts +37 -0
  80. package/dist/primitives/signup.d.ts.map +1 -0
  81. package/dist/primitives/signup.js +32 -0
  82. package/dist/primitives/signup.js.map +1 -0
  83. package/dist/primitives/state.d.ts +132 -0
  84. package/dist/primitives/state.d.ts.map +1 -0
  85. package/dist/primitives/state.js +167 -0
  86. package/dist/primitives/state.js.map +1 -0
  87. package/dist/primitives/storage.d.ts +132 -0
  88. package/dist/primitives/storage.d.ts.map +1 -0
  89. package/dist/primitives/storage.js +275 -0
  90. package/dist/primitives/storage.js.map +1 -0
  91. package/dist/primitives/theme.d.ts +106 -0
  92. package/dist/primitives/theme.d.ts.map +1 -0
  93. package/dist/primitives/theme.js +187 -0
  94. package/dist/primitives/theme.js.map +1 -0
  95. package/dist/primitives/version.d.ts +50 -0
  96. package/dist/primitives/version.d.ts.map +1 -0
  97. package/dist/primitives/version.js +62 -0
  98. package/dist/primitives/version.js.map +1 -0
  99. package/dist/provider.d.ts +36 -0
  100. package/dist/provider.d.ts.map +1 -0
  101. package/dist/provider.jsx +71 -0
  102. package/dist/provider.jsx.map +1 -0
  103. package/dist/types.d.ts +82 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +7 -0
  106. package/dist/types.js.map +1 -0
  107. package/package.json +58 -0
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Solid.js primitive for OAuth authentication.
3
+ *
4
+ * Builds provider initiation URLs, starts the full-page redirect flow, and
5
+ * automatically handles the OAuth callback: when the page loads with a `code`
6
+ * (+ optional `state`) URL parameter and a stashed provider, the code is
7
+ * exchanged for a session via `POST {baseURL}{loginEndpoint}`.
8
+ *
9
+ * Session establishment prefers an auth client — an explicit
10
+ * {@link CreateOAuthOptions.authClient} override, else the surrounding
11
+ * `MoleculeProvider`'s client. Without any client, the code exchange itself
12
+ * has already established the httpOnly-cookie session server-side, so a
13
+ * user-carrying response still counts as a successful login.
14
+ *
15
+ * @module
16
+ */
17
+ import { getOwner, onMount } from 'solid-js';
18
+ import { getAuthClient } from '../context.js';
19
+ /**
20
+ * Creates OAuth helpers.
21
+ *
22
+ * Automatically handles OAuth callbacks by detecting `code` and `state` URL
23
+ * parameters and exchanging them for a session:
24
+ * - Inside a Solid owner (component setup / `createRoot`), the callback
25
+ * handling is deferred to `onMount` so it runs client-side after mount.
26
+ * - Outside an owner (a plain function call, e.g. bootstrap code), it runs
27
+ * immediately at creation, browser-guarded.
28
+ *
29
+ * @param options - OAuth configuration
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * const { providers, getOAuthUrl, redirect } = createOAuth({
34
+ * baseURL: 'https://api.example.com',
35
+ * oauthProviders: ['github', 'google'],
36
+ * onSuccess: () => navigate('/dashboard'),
37
+ * onError: (error) => setErrorMessage(error),
38
+ * })
39
+ *
40
+ * return (
41
+ * <For each={providers()}>
42
+ * {(provider) => (
43
+ * <button onClick={() => redirect(provider)}>
44
+ * Login with {provider}
45
+ * </button>
46
+ * )}
47
+ * </For>
48
+ * )
49
+ * ```
50
+ * @returns The created instance.
51
+ */
52
+ export function createOAuth(options) {
53
+ const baseURL = options?.baseURL ?? '';
54
+ const oauthEndpoint = options?.oauthEndpoint ?? '/oauth';
55
+ const loginEndpoint = options?.loginEndpoint ?? '/users/log-in/oauth';
56
+ const providersList = options?.oauthProviders ?? [];
57
+ const providers = () => providersList;
58
+ // Resolve the auth client once at creation: an explicit override wins;
59
+ // otherwise fall back to the surrounding MoleculeProvider context.
60
+ let authClient = options?.authClient ?? null;
61
+ if (!authClient) {
62
+ try {
63
+ authClient = getAuthClient();
64
+ }
65
+ catch (_error) {
66
+ // Intentional noop: created outside a MoleculeProvider (or without auth
67
+ // configured). The helper still works — handleCallback falls back to the
68
+ // server-established httpOnly-cookie session (see its JSDoc).
69
+ authClient = null;
70
+ }
71
+ }
72
+ const getOAuthUrl = (provider) => {
73
+ // Encode the provider as a single path segment so a (future) caller passing an
74
+ // untrusted value can never inject a path/query/scheme into the opened URL —
75
+ // defense-in-depth on top of the upstream static provider allowlist. Plain
76
+ // provider names ('github', 'google') pass through unchanged.
77
+ return `${baseURL}${oauthEndpoint}/${encodeURIComponent(provider)}`;
78
+ };
79
+ /** Stash which provider initiated the flow so the callback knows it's ours. */
80
+ const stashProvider = (provider) => {
81
+ try {
82
+ sessionStorage.setItem('oauth_provider', provider);
83
+ }
84
+ catch (_error) {
85
+ /* SSR-safe — sessionStorage is unavailable in SSR/sandboxed environments */
86
+ }
87
+ };
88
+ /**
89
+ * Append the current page's PATH as `redirect_to` so the api's initiation
90
+ * endpoint (`GET /users/oauth/:provider`) builds a provider `redirect_uri`
91
+ * that lands the callback back on THIS page — the one with `createOAuth`
92
+ * mounted (e.g. `/login`) — instead of the app root, where nothing may be
93
+ * listening for the `code` param. Path only (no origin/query): the server
94
+ * validates it as a same-origin absolute path, so it can never become an
95
+ * open redirect. Servers that predate the param simply ignore it.
96
+ */
97
+ const withReturnPath = (url) => {
98
+ const path = typeof window !== 'undefined' ? window.location.pathname : '';
99
+ if (!path || path === '/')
100
+ return url;
101
+ return `${url}${url.includes('?') ? '&' : '?'}redirect_to=${encodeURIComponent(path)}`;
102
+ };
103
+ const redirect = (provider) => {
104
+ stashProvider(provider);
105
+ window.location.href = withReturnPath(getOAuthUrl(provider));
106
+ };
107
+ /** Surface a failure message to the configured error callback. */
108
+ const surfaceError = (error) => {
109
+ options?.onError?.(error);
110
+ };
111
+ /**
112
+ * Establish the authenticated session from an exchange result: seed the
113
+ * access token + user and let `initialize()` flip `authenticated`. Mirrors
114
+ * what `authClient.login()` does for password login. Returns whether a user
115
+ * was set (a result with no user is not a real session).
116
+ */
117
+ const establishSession = async (client, token, user) => {
118
+ // Seed the token via the auth client's configured token storage adapter
119
+ // (in-memory by default) — NOT localStorage directly. Writing the bearer
120
+ // token to localStorage violates the in-memory-default storage contract and
121
+ // makes it JS-readable (XSS-exfiltratable).
122
+ if (token)
123
+ client.setAccessToken(token);
124
+ if (user && typeof user === 'object') {
125
+ client.setUser(user);
126
+ await client.initialize();
127
+ return true;
128
+ }
129
+ return false;
130
+ };
131
+ const handleCallback = async () => {
132
+ if (typeof window === 'undefined')
133
+ return;
134
+ const params = new URLSearchParams(window.location.search);
135
+ const code = params.get('code');
136
+ const state = params.get('state');
137
+ if (!code)
138
+ return;
139
+ // Retrieve the provider that initiated the flow
140
+ let provider = null;
141
+ try {
142
+ provider = sessionStorage.getItem('oauth_provider');
143
+ }
144
+ catch (_error) {
145
+ /* SSR-safe — sessionStorage is unavailable in SSR/sandboxed environments */
146
+ }
147
+ if (!provider)
148
+ return;
149
+ // Clean up URL (remove code/state params) and sessionStorage
150
+ const cleanUrl = new URL(window.location.href);
151
+ cleanUrl.searchParams.delete('code');
152
+ cleanUrl.searchParams.delete('state');
153
+ window.history.replaceState({}, '', cleanUrl.toString());
154
+ try {
155
+ sessionStorage.removeItem('oauth_provider');
156
+ }
157
+ catch (_error) {
158
+ /* SSR-safe — sessionStorage is unavailable in SSR/sandboxed environments */
159
+ }
160
+ // Exchange code for session
161
+ try {
162
+ const response = await fetch(`${baseURL}${loginEndpoint}`, {
163
+ method: 'POST',
164
+ headers: { 'Content-Type': 'application/json' },
165
+ credentials: 'include', // Send cookies (oauth_state) for state validation
166
+ body: JSON.stringify({
167
+ server: provider,
168
+ code,
169
+ state: state || undefined,
170
+ redirect_uri: window.location.origin,
171
+ }),
172
+ });
173
+ if (!response.ok) {
174
+ const data = (await response.json().catch(() => null));
175
+ surfaceError(data && typeof data.error === 'string' && data.error ? data.error : 'OAuth login failed');
176
+ return;
177
+ }
178
+ const data = await response.json().catch(() => null);
179
+ // Store the token from the response
180
+ const authHeader = response.headers.get('authorization') || response.headers.get('set-authorization');
181
+ const token = authHeader ? authHeader.replace('Bearer ', '') : null;
182
+ // The authenticated user is `props` (molecule resource convention) or `user`
183
+ // (generic AuthResult). OAuth issues no refresh token, so we carry the token +
184
+ // user to whoever will own the session.
185
+ const user = data && typeof data === 'object'
186
+ ? (data.props ??
187
+ data.user ??
188
+ null)
189
+ : null;
190
+ if (authClient) {
191
+ const ok = await establishSession(authClient, token, user);
192
+ if (ok)
193
+ options?.onSuccess?.();
194
+ else
195
+ surfaceError('OAuth login failed');
196
+ return;
197
+ }
198
+ // No auth client available: the server already established the
199
+ // httpOnly-cookie session during the code exchange, so a user-carrying
200
+ // response still counts as a successful login. A response with no user
201
+ // means no session was established — surface the failure.
202
+ if (user && typeof user === 'object')
203
+ options?.onSuccess?.();
204
+ else
205
+ surfaceError('OAuth login failed');
206
+ }
207
+ catch (err) {
208
+ surfaceError(err instanceof Error && err.message ? err.message : 'OAuth login failed');
209
+ }
210
+ };
211
+ // Auto-handle the OAuth callback:
212
+ // - Inside a Solid owner (component setup / createRoot), defer to onMount
213
+ // so the exchange runs client-side after the component mounts.
214
+ // - Outside an owner (plain function call — e.g. bootstrap code), run
215
+ // immediately, browser-guarded. handleCallback itself no-ops unless the
216
+ // URL carries a `code` param and a provider was stashed.
217
+ if (getOwner()) {
218
+ onMount(() => {
219
+ void handleCallback();
220
+ });
221
+ }
222
+ else if (typeof window !== 'undefined') {
223
+ void handleCallback();
224
+ }
225
+ return {
226
+ providers,
227
+ getOAuthUrl,
228
+ redirect,
229
+ handleCallback,
230
+ };
231
+ }
232
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/primitives/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Solid.js primitive for password reset with async state tracking.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Accessor } from 'solid-js';
7
+ import type { PasswordResetConfirm, PasswordResetRequest } from '@molecule/app-auth';
8
+ import type { PromiseState } from '@molecule/app-utilities';
9
+ /**
10
+ * Return type for createPasswordReset primitive.
11
+ */
12
+ export interface CreatePasswordResetReturn {
13
+ requestState: Accessor<PromiseState<void>>;
14
+ confirmState: Accessor<PromiseState<void>>;
15
+ requestReset: (data: PasswordResetRequest) => Promise<void>;
16
+ confirmReset: (data: PasswordResetConfirm) => Promise<void>;
17
+ reset: () => void;
18
+ }
19
+ /**
20
+ * Creates a password reset primitive with async state tracking.
21
+ *
22
+ * @returns Password reset state and actions
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const { requestState, confirmState, requestReset, confirmReset } = createPasswordReset()
27
+ *
28
+ * // Request phase
29
+ * <button
30
+ * onClick={() => requestReset({ email: email() })}
31
+ * disabled={requestState().status === 'pending'}
32
+ * >
33
+ * Send Reset Email
34
+ * </button>
35
+ *
36
+ * // Confirm phase
37
+ * <button
38
+ * onClick={() => confirmReset({ token: token(), password: password() })}
39
+ * disabled={confirmState().status === 'pending'}
40
+ * >
41
+ * Reset Password
42
+ * </button>
43
+ * ```
44
+ */
45
+ export declare function createPasswordReset(): CreatePasswordResetReturn;
46
+ //# sourceMappingURL=password-reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-reset.d.ts","sourceRoot":"","sources":["../../src/primitives/password-reset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAK3D;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1C,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1C,YAAY,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,YAAY,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mBAAmB,IAAI,yBAAyB,CAiB/D"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Solid.js primitive for password reset with async state tracking.
3
+ *
4
+ * @module
5
+ */
6
+ import { getAuthClient } from '../context.js';
7
+ import { createPromise } from './promise.js';
8
+ /**
9
+ * Creates a password reset primitive with async state tracking.
10
+ *
11
+ * @returns Password reset state and actions
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const { requestState, confirmState, requestReset, confirmReset } = createPasswordReset()
16
+ *
17
+ * // Request phase
18
+ * <button
19
+ * onClick={() => requestReset({ email: email() })}
20
+ * disabled={requestState().status === 'pending'}
21
+ * >
22
+ * Send Reset Email
23
+ * </button>
24
+ *
25
+ * // Confirm phase
26
+ * <button
27
+ * onClick={() => confirmReset({ token: token(), password: password() })}
28
+ * disabled={confirmState().status === 'pending'}
29
+ * >
30
+ * Reset Password
31
+ * </button>
32
+ * ```
33
+ */
34
+ export function createPasswordReset() {
35
+ const client = getAuthClient();
36
+ const request = createPromise((data) => client.requestPasswordReset(data));
37
+ const confirm = createPromise((data) => client.confirmPasswordReset(data));
38
+ return {
39
+ requestState: request.state,
40
+ confirmState: confirm.state,
41
+ requestReset: request.call,
42
+ confirmReset: confirm.call,
43
+ reset: () => {
44
+ request.reset();
45
+ confirm.reset();
46
+ },
47
+ };
48
+ }
49
+ //# sourceMappingURL=password-reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-reset.js","sourceRoot":"","sources":["../../src/primitives/password-reset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAa5C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAE9B,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,IAA0B,EAAE,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;IAEhG,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,IAA0B,EAAE,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;IAEhG,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,KAAK;QAC3B,YAAY,EAAE,OAAO,CAAC,KAAK;QAC3B,YAAY,EAAE,OAAO,CAAC,IAAI;QAC1B,YAAY,EAAE,OAAO,CAAC,IAAI;QAC1B,KAAK,EAAE,GAAG,EAAE;YACV,OAAO,CAAC,KAAK,EAAE,CAAA;YACf,OAAO,CAAC,KAAK,EAAE,CAAA;QACjB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Solid.js primitives for platform detection.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Platform } from '@molecule/app-platform';
7
+ /**
8
+ * Platform primitives return type.
9
+ */
10
+ export interface PlatformPrimitives {
11
+ platform: Platform;
12
+ isNative: boolean;
13
+ isMobile: boolean;
14
+ isDesktop: boolean;
15
+ isWeb: boolean;
16
+ isDevelopment: boolean;
17
+ isProduction: boolean;
18
+ isPlatform: (...platforms: Platform[]) => boolean;
19
+ }
20
+ /**
21
+ * Create platform primitives for detecting the current platform.
22
+ *
23
+ * This is a static primitive (no reactive signals) since the platform
24
+ * does not change during the lifecycle of the app.
25
+ *
26
+ * @returns Platform primitives object
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * import { createPlatform } from '@molecule/app-solid'
31
+ *
32
+ * function PlatformInfo() {
33
+ * const { platform, isWeb, isMobile, isPlatform } = createPlatform()
34
+ *
35
+ * return (
36
+ * <div>
37
+ * <p>Platform: {platform}</p>
38
+ * <p>Is Web: {isWeb ? 'Yes' : 'No'}</p>
39
+ * <Show when={isPlatform('ios', 'android')}>
40
+ * <p>Running on mobile native</p>
41
+ * </Show>
42
+ * </div>
43
+ * )
44
+ * }
45
+ * ```
46
+ */
47
+ export declare function createPlatform(): PlatformPrimitives;
48
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/primitives/platform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAGtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;IACrB,UAAU,EAAE,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAA;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,IAAI,kBAAkB,CAanD"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Solid.js primitives for platform detection.
3
+ *
4
+ * @module
5
+ */
6
+ import { isPlatform, platform } from '@molecule/app-platform';
7
+ /**
8
+ * Create platform primitives for detecting the current platform.
9
+ *
10
+ * This is a static primitive (no reactive signals) since the platform
11
+ * does not change during the lifecycle of the app.
12
+ *
13
+ * @returns Platform primitives object
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { createPlatform } from '@molecule/app-solid'
18
+ *
19
+ * function PlatformInfo() {
20
+ * const { platform, isWeb, isMobile, isPlatform } = createPlatform()
21
+ *
22
+ * return (
23
+ * <div>
24
+ * <p>Platform: {platform}</p>
25
+ * <p>Is Web: {isWeb ? 'Yes' : 'No'}</p>
26
+ * <Show when={isPlatform('ios', 'android')}>
27
+ * <p>Running on mobile native</p>
28
+ * </Show>
29
+ * </div>
30
+ * )
31
+ * }
32
+ * ```
33
+ */
34
+ export function createPlatform() {
35
+ const info = platform();
36
+ return {
37
+ platform: info.platform,
38
+ isNative: info.isNative,
39
+ isMobile: info.isMobile,
40
+ isDesktop: info.isDesktop,
41
+ isWeb: info.isWeb,
42
+ isDevelopment: info.isDevelopment,
43
+ isProduction: info.isProduction,
44
+ isPlatform: (...platforms) => isPlatform(...platforms),
45
+ };
46
+ }
47
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/primitives/platform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAgB7D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAA;IAEvB,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,UAAU,EAAE,CAAC,GAAG,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;KACvD,CAAA;AACH,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Solid.js primitive for tracking async function state.
3
+ *
4
+ * @module
5
+ */
6
+ import type { PromiseState } from '@molecule/app-utilities';
7
+ /**
8
+ * Promise state accessor with actions.
9
+ */
10
+ export interface CreatePromiseReturn<T> {
11
+ state: () => PromiseState<T>;
12
+ call: (...args: any[]) => Promise<T>;
13
+ cancel: (message?: string) => void;
14
+ reset: () => void;
15
+ }
16
+ /**
17
+ * Primitive that wraps an async function with reactive state tracking.
18
+ *
19
+ * @param asyncFn - The async function to wrap
20
+ * @returns Object with state accessor, call, cancel, and reset functions
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * import { createPromise } from '@molecule/app-solid'
25
+ *
26
+ * function UserLoader() {
27
+ * const { state, call } = createPromise((id: string) => fetchUser(id))
28
+ *
29
+ * return (
30
+ * <div>
31
+ * <button onClick={() => call('123')} disabled={state().status === 'pending'}>
32
+ * {state().status === 'pending' ? 'Loading...' : 'Fetch User'}
33
+ * </button>
34
+ * <Show when={state().value}>
35
+ * <div>{state().value!.name}</div>
36
+ * </Show>
37
+ * <Show when={state().error}>
38
+ * <div>Error: {state().error!.message}</div>
39
+ * </Show>
40
+ * </div>
41
+ * )
42
+ * }
43
+ * ```
44
+ */
45
+ export declare function createPromise<T extends (...args: any[]) => Promise<any>>(asyncFn: T): CreatePromiseReturn<Awaited<ReturnType<T>>>;
46
+ //# sourceMappingURL=promise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/primitives/promise.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,yBAAyB,CAAA;AAE1E;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IAC5B,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IACpC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EACtE,OAAO,EAAE,CAAC,GACT,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CA8E7C"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Solid.js primitive for tracking async function state.
3
+ *
4
+ * @module
5
+ */
6
+ /* eslint-disable @typescript-eslint/no-explicit-any */
7
+ import { batch, createSignal, onCleanup } from 'solid-js';
8
+ const INITIAL_STATE = {
9
+ status: 'idle',
10
+ value: null,
11
+ error: null,
12
+ };
13
+ /**
14
+ * Primitive that wraps an async function with reactive state tracking.
15
+ *
16
+ * @param asyncFn - The async function to wrap
17
+ * @returns Object with state accessor, call, cancel, and reset functions
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * import { createPromise } from '@molecule/app-solid'
22
+ *
23
+ * function UserLoader() {
24
+ * const { state, call } = createPromise((id: string) => fetchUser(id))
25
+ *
26
+ * return (
27
+ * <div>
28
+ * <button onClick={() => call('123')} disabled={state().status === 'pending'}>
29
+ * {state().status === 'pending' ? 'Loading...' : 'Fetch User'}
30
+ * </button>
31
+ * <Show when={state().value}>
32
+ * <div>{state().value!.name}</div>
33
+ * </Show>
34
+ * <Show when={state().error}>
35
+ * <div>Error: {state().error!.message}</div>
36
+ * </Show>
37
+ * </div>
38
+ * )
39
+ * }
40
+ * ```
41
+ */
42
+ export function createPromise(asyncFn) {
43
+ const [state, setState] = createSignal(INITIAL_STATE);
44
+ let callId = 0;
45
+ let cleaned = false;
46
+ onCleanup(() => {
47
+ cleaned = true;
48
+ });
49
+ const call = (...args) => {
50
+ callId += 1;
51
+ const thisCallId = callId;
52
+ batch(() => {
53
+ setState({
54
+ status: 'pending',
55
+ value: null,
56
+ error: null,
57
+ });
58
+ });
59
+ return asyncFn(...args).then((resolved) => {
60
+ if (thisCallId === callId && !cleaned) {
61
+ batch(() => {
62
+ setState({
63
+ status: 'resolved',
64
+ value: resolved,
65
+ error: null,
66
+ });
67
+ });
68
+ }
69
+ return resolved;
70
+ }, (err) => {
71
+ const rejection = err instanceof Error ? err : new Error(String(err));
72
+ if (thisCallId === callId && !cleaned) {
73
+ batch(() => {
74
+ setState({
75
+ status: 'rejected',
76
+ value: null,
77
+ error: rejection,
78
+ });
79
+ });
80
+ }
81
+ throw rejection;
82
+ });
83
+ };
84
+ const cancel = (message) => {
85
+ callId += 1;
86
+ if (!cleaned) {
87
+ batch(() => {
88
+ setState({
89
+ status: 'rejected',
90
+ value: null,
91
+ error: message ? new Error(message) : null,
92
+ });
93
+ });
94
+ }
95
+ };
96
+ const reset = () => {
97
+ callId += 1;
98
+ if (!cleaned) {
99
+ setState(INITIAL_STATE);
100
+ }
101
+ };
102
+ return { state, call, cancel, reset };
103
+ }
104
+ //# sourceMappingURL=promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.js","sourceRoot":"","sources":["../../src/primitives/promise.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uDAAuD;AACvD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAczD,MAAM,aAAa,GAAwB;IACzC,MAAM,EAAE,MAAuB;IAC/B,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;CACZ,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAU;IAIV,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAkB,aAAgC,CAAC,CAAA;IAEzF,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,IAAI,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,CAAC,GAAG,IAAW,EAAc,EAAE;QAC1C,MAAM,IAAI,CAAC,CAAA;QACX,MAAM,UAAU,GAAG,MAAM,CAAA;QAEzB,KAAK,CAAC,GAAG,EAAE;YACT,QAAQ,CAAC;gBACP,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,IAAI;aACZ,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,OAAO,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAC1B,CAAC,QAAW,EAAE,EAAE;YACd,IAAI,UAAU,KAAK,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtC,KAAK,CAAC,GAAG,EAAE;oBACT,QAAQ,CAAC;wBACP,MAAM,EAAE,UAAU;wBAClB,KAAK,EAAE,QAAQ;wBACf,KAAK,EAAE,IAAI;qBACZ,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;YACJ,CAAC;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC,EACD,CAAC,GAAY,EAAE,EAAE;YACf,MAAM,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YAErE,IAAI,UAAU,KAAK,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtC,KAAK,CAAC,GAAG,EAAE;oBACT,QAAQ,CAAC;wBACP,MAAM,EAAE,UAAU;wBAClB,KAAK,EAAE,IAAI;wBACX,KAAK,EAAE,SAAS;qBACjB,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,SAAS,CAAA;QACjB,CAAC,CACF,CAAA;IACH,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAQ,EAAE;QACxC,MAAM,IAAI,CAAC,CAAA;QAEX,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,KAAK,CAAC,GAAG,EAAE;gBACT,QAAQ,CAAC;oBACP,MAAM,EAAE,UAAU;oBAClB,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;iBAC3C,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,MAAM,IAAI,CAAC,CAAA;QAEX,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,CAAC,aAAgC,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC,CAAA;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AACvC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Solid.js primitives for push notifications.
3
+ *
4
+ * @module
5
+ */
6
+ import { type Accessor } from 'solid-js';
7
+ import type { NotificationActionListener, NotificationReceivedListener, PermissionStatus, PushRegisterOptions, PushToken, TokenChangeListener } from '@molecule/app-push';
8
+ /**
9
+ * Push primitives return type.
10
+ */
11
+ export interface PushPrimitives {
12
+ permission: Accessor<PermissionStatus | null>;
13
+ token: Accessor<PushToken | null>;
14
+ checkPermission: () => Promise<PermissionStatus>;
15
+ requestPermission: () => Promise<PermissionStatus>;
16
+ register: (options?: PushRegisterOptions) => Promise<PushToken>;
17
+ unregister: () => Promise<void>;
18
+ onNotificationReceived: (listener: NotificationReceivedListener) => () => void;
19
+ onNotificationAction: (listener: NotificationActionListener) => () => void;
20
+ onTokenChange: (listener: TokenChangeListener) => () => void;
21
+ setBadge: (count: number) => Promise<void>;
22
+ clearBadge: () => Promise<void>;
23
+ }
24
+ /**
25
+ * Create push notification primitives.
26
+ *
27
+ * @returns Push primitives object
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * import { createPush } from '@molecule/app-solid'
32
+ *
33
+ * function NotificationButton() {
34
+ * const { permission, requestPermission, register } = createPush()
35
+ *
36
+ * const handleEnable = async () => {
37
+ * const status = await requestPermission()
38
+ * if (status === 'granted') {
39
+ * await register()
40
+ * }
41
+ * }
42
+ *
43
+ * return (
44
+ * <Show when={permission() !== 'granted'}>
45
+ * <button onClick={handleEnable}>Enable Notifications</button>
46
+ * </Show>
47
+ * )
48
+ * }
49
+ * ```
50
+ */
51
+ export declare function createPush(): PushPrimitives;
52
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/primitives/push.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,QAAQ,EAAgB,MAAM,UAAU,CAAA;AAEtD,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAG3B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAC7C,KAAK,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IACjC,eAAe,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAChD,iBAAiB,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAClD,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/D,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,sBAAsB,EAAE,CAAC,QAAQ,EAAE,4BAA4B,KAAK,MAAM,IAAI,CAAA;IAC9E,oBAAoB,EAAE,CAAC,QAAQ,EAAE,0BAA0B,KAAK,MAAM,IAAI,CAAA;IAC1E,aAAa,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,MAAM,IAAI,CAAA;IAC5D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,IAAI,cAAc,CA0C3C"}