@worthai/onboarding-sdk 2.0.17 โ 3.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -202
- package/dist-sdk/sdk3/createWorthOnboarding.d.ts +2 -0
- package/dist-sdk/sdk3/errors.d.ts +24 -0
- package/dist-sdk/sdk3/index-XF4bH3Uu.js +12301 -0
- package/dist-sdk/sdk3/index.d.ts +3 -0
- package/dist-sdk/sdk3/index.js +6 -0
- package/dist-sdk/sdk3/runtimeAdapter-B5Q9gkTA.js +22644 -0
- package/dist-sdk/sdk3/runtimeAdapter.d.ts +7 -0
- package/dist-sdk/sdk3/runtimeAdapterHydration.d.ts +8 -0
- package/dist-sdk/sdk3/styleManager.d.ts +1 -0
- package/dist-sdk/sdk3/worthOnboarding.d.ts +27 -0
- package/dist-sdk/sdk3/worthOnboarding.types.d.ts +307 -0
- package/dist-sdk/sdk3/worthai-onboarding-sdk.global.js +3424 -0
- package/package.json +78 -38
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -279
- package/dist/index.js.map +0 -1
- package/dist/interfaces/AnyMessage.d.ts +0 -4
- package/dist/interfaces/ChildSite.d.ts +0 -2
- package/dist/interfaces/ChildSiteMessage.d.ts +0 -8
- package/dist/interfaces/ChildSiteSubscription.d.ts +0 -2
- package/dist/interfaces/DetachedEvent.d.ts +0 -73
- package/dist/interfaces/IframeMode.d.ts +0 -1
- package/dist/interfaces/IframeQueryParams.d.ts +0 -1
- package/dist/interfaces/OnboardingApp.d.ts +0 -2
- package/dist/interfaces/OnboardingAppAppSubscription.d.ts +0 -2
- package/dist/interfaces/OnboardingAppMessage.d.ts +0 -41
- package/dist/interfaces/OnboardingAppMode.d.ts +0 -2
- package/dist/interfaces/OnboardingAppSubscription.d.ts +0 -2
- package/dist/interfaces/OnboardingConsumerApp.d.ts +0 -2
- package/dist/interfaces/OnboardingConsumerAppMessage.d.ts +0 -17
- package/dist/interfaces/ParentSite.d.ts +0 -2
- package/dist/interfaces/ParentSiteMessage.d.ts +0 -26
- package/dist/interfaces/ParentSiteSubscription.d.ts +0 -2
- package/dist/interfaces/QueryParams.d.ts +0 -1
- package/dist/interfaces/StageNavigation.d.ts +0 -21
- package/dist/interfaces/index.d.ts +0 -19
- package/dist/mockServiceWorker.js +0 -349
- package/dist/mocks/browser.d.ts +0 -1
- package/dist/mocks/handlers/authHandler.d.ts +0 -1
- package/dist/mocks/handlers/index.d.ts +0 -1
- package/dist/utils/createChildSite/index.d.ts +0 -23
- package/dist/utils/createOnboardingApp/index.d.ts +0 -20
- package/dist/utils/createOnboardingConsumerApp/index.d.ts +0 -9
- package/dist/utils/createParentSite/index.d.ts +0 -10
- package/dist/utils/getURLQueryParams/index.d.ts +0 -2
- package/dist/utils/index.d.ts +0 -4
package/README.md
CHANGED
|
@@ -1,276 +1,293 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Onboarding Application
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Install
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
### Within the monorepo
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Add as workspace dependency
|
|
11
|
-
pnpm add @worthai/onboarding-sdk@workspace:*
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
### External projects
|
|
5
|
+
This project uses [pnpm](https://pnpm.io) for dependency management. See
|
|
6
|
+
[pnpm vs npm](https://pnpm.io/pnpm-vs-npm) for how pnpm differs from npm.
|
|
15
7
|
|
|
16
8
|
```bash
|
|
17
|
-
|
|
18
|
-
npm install @worthai/onboarding-sdk
|
|
19
|
-
|
|
20
|
-
# Using pnpm
|
|
21
|
-
pnpm install @worthai/onboarding-sdk
|
|
9
|
+
pnpm install
|
|
22
10
|
```
|
|
23
11
|
|
|
24
|
-
##
|
|
12
|
+
## Run Locally
|
|
25
13
|
|
|
26
|
-
###
|
|
14
|
+
### Development
|
|
27
15
|
|
|
28
|
-
|
|
16
|
+
Start the development server:
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
```bash
|
|
19
|
+
pnpm dev
|
|
20
|
+
```
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
import { createOnboardingApp } from '@worthai/onboarding-sdk';
|
|
22
|
+
Then open
|
|
36
23
|
|
|
37
|
-
|
|
38
|
-
const onboardingApp = createOnboardingApp({
|
|
39
|
-
origin: 'https://onboarding-app.com',
|
|
40
|
-
inviteToken: 'YOUR_INVITE_TOKEN',
|
|
41
|
-
mode: 'embedded',
|
|
42
|
-
});
|
|
24
|
+
โ Local: [http://localhost:5180](http://localhost:5180)
|
|
43
25
|
|
|
44
|
-
|
|
45
|
-
const subscription = onboardingApp.subscribe((event) => {
|
|
46
|
-
if (event.data.type === 'ROUTE_URL') {
|
|
47
|
-
console.log('Current route:', event.data.payload.url);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
26
|
+
โ Network: shown in your terminal output, if needed
|
|
50
27
|
|
|
51
|
-
|
|
52
|
-
// subscription.unsubscribe();
|
|
28
|
+
### Optimized Build + Serve
|
|
53
29
|
|
|
54
|
-
|
|
55
|
-
document
|
|
56
|
-
.getElementById('onboarding-container')
|
|
57
|
-
.appendChild(onboardingApp.iframe);
|
|
30
|
+
To test an optimized production build locally:
|
|
58
31
|
|
|
59
|
-
|
|
32
|
+
```bash
|
|
33
|
+
pnpm build
|
|
34
|
+
pnpm start
|
|
35
|
+
```
|
|
60
36
|
|
|
61
|
-
|
|
62
|
-
|
|
37
|
+
Then open
|
|
38
|
+
|
|
39
|
+
โ Local: [http://localhost:4173](http://localhost:4173)
|
|
40
|
+
|
|
41
|
+
โ Network: shown in your terminal output, if needed
|
|
63
42
|
|
|
64
|
-
|
|
65
|
-
prevButton && prevButton.addEventListener('click', () => onboardingApp.prev());
|
|
43
|
+
## Test
|
|
66
44
|
|
|
67
|
-
|
|
68
|
-
nextButton && nextButton.addEventListener('click', () => onboardingApp.next());
|
|
45
|
+
Run the test suite:
|
|
69
46
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// <button id="onboarding-prev">Back</button>
|
|
73
|
-
// <button id="onboarding-next">Next</button>
|
|
47
|
+
```bash
|
|
48
|
+
pnpm test
|
|
74
49
|
```
|
|
75
50
|
|
|
76
|
-
|
|
51
|
+
`vitest` starts in watch mode by default, which is useful during local
|
|
52
|
+
development because it reruns tests as files change. `vitest run` runs the test
|
|
53
|
+
suite once and exits, good for single run checks before putting a PR up for review.
|
|
77
54
|
|
|
78
|
-
|
|
55
|
+
Run tests with coverage:
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
```bash
|
|
58
|
+
pnpm test:coverage
|
|
59
|
+
```
|
|
81
60
|
|
|
82
|
-
|
|
83
|
-
import { createOnboardingConsumerApp } from '@worthai/onboarding-sdk';
|
|
61
|
+
Open the Vitest UI:
|
|
84
62
|
|
|
85
|
-
|
|
86
|
-
|
|
63
|
+
```bash
|
|
64
|
+
pnpm test:ui
|
|
65
|
+
```
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
consumerApp.postMessage({
|
|
90
|
-
type: "ROUTE_URL";
|
|
91
|
-
payload: {
|
|
92
|
-
url: '/getting-started';
|
|
93
|
-
};
|
|
94
|
-
});
|
|
67
|
+
## Check
|
|
95
68
|
|
|
96
|
-
|
|
97
|
-
const subscription = consumerApp.subscribe((event) => {
|
|
98
|
-
if (event.data.type === 'NEXT_STAGE') {
|
|
99
|
-
// Navigate to next stage
|
|
100
|
-
}
|
|
101
|
-
});
|
|
69
|
+
Run quality checks:
|
|
102
70
|
|
|
103
|
-
|
|
104
|
-
|
|
71
|
+
```bash
|
|
72
|
+
pnpm check
|
|
105
73
|
```
|
|
106
74
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
### OnboardingAppMessage Events (Child โ Parent)
|
|
75
|
+
PRs going into `main` will be required to pass both quality and test checks before
|
|
76
|
+
they can be merged. Before requesting a PR into `main`, run both the quality check and the test suite locally.
|
|
110
77
|
|
|
111
|
-
|
|
112
|
-
| -------------------- | ---------------------------------------------------------------------- |
|
|
113
|
-
| `ROUTE_URL` | Notifies parent site of current route changes in onboarding app |
|
|
114
|
-
| `IFRAME_RESIZE` | Notifies parent site when the iframe needs to resize (includes height) |
|
|
115
|
-
| `IFRAME_INITIALIZED` | Notifies parent site when the iframe has finished initializing |
|
|
78
|
+
## SDK 3 Package Boundary
|
|
116
79
|
|
|
117
|
-
|
|
80
|
+
This repository is the source for the SDK 3 onboarding package surface. The SDK
|
|
81
|
+
entrypoint is isolated from the app entrypoint so the existing `/onboarding` app
|
|
82
|
+
build remains deployable.
|
|
118
83
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
| `NEXT_STAGE` | Navigates the onboarding app to the next stage |
|
|
122
|
-
| `PREV_STAGE` | Navigates the onboarding app to the previous stage |
|
|
123
|
-
| `SKIP_STAGE` | Skips the current stage in the onboarding app |
|
|
124
|
-
| `INVITE_TOKEN_SENT` | Notifies child site that an invite token has been sent (includes token) |
|
|
125
|
-
| `IFRAME_RENDERED_ON_PARENT_SITE` | Notifies child site that the iframe has been rendered on the parent site |
|
|
126
|
-
| `REFRESH_SIZE` | Requests the child site to refresh its size |
|
|
127
|
-
| `IFRAME_INITIALIZED` | Notifies child site that the iframe has been initialized (includes mode) |
|
|
128
|
-
| `SET_CUSTOM_CSS` | Sets custom CSS styles for the iframe (includes CSS string) |
|
|
129
|
-
| `SET_IFRAME_MODE` | Sets the iframe mode (includes mode: 'embedded', 'non-embedded', or undefined) |
|
|
84
|
+
```ts
|
|
85
|
+
import { createWorthOnboarding } from '@worthai/onboarding-sdk';
|
|
130
86
|
|
|
131
|
-
|
|
87
|
+
const onboarding = createWorthOnboarding({
|
|
88
|
+
apiBaseUrl: 'https://api.example.com',
|
|
89
|
+
inviteToken: 'INVITE_TOKEN'
|
|
90
|
+
});
|
|
132
91
|
|
|
133
|
-
|
|
92
|
+
await onboarding.mount('#worth-onboarding');
|
|
93
|
+
```
|
|
134
94
|
|
|
135
|
-
|
|
95
|
+
The SDK owns an in-memory router for the mounted onboarding flow so customer
|
|
96
|
+
pages do not need to serve or navigate under `/onboarding`.
|
|
136
97
|
|
|
137
|
-
|
|
138
|
-
|
|
98
|
+
Production SDK usage does not require service path configuration. The SDK owns
|
|
99
|
+
the auth, case, and integration service prefixes used by the embedded runtime.
|
|
100
|
+
Use the optional `apiBaseUrl` option only for local, staging, or other non-default
|
|
101
|
+
API origins.
|
|
102
|
+
Styles are injected automatically during `mount()`. Hosts with a strict
|
|
103
|
+
`style-src` Content Security Policy can pass `styleNonce` with their
|
|
104
|
+
request-level CSP nonce.
|
|
139
105
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
106
|
+
SDK browser storage and IndexedDB state are namespaced under
|
|
107
|
+
`worth:onboarding-sdk` by default. Consumers can override this with
|
|
108
|
+
`storageNamespace` for deterministic isolation, but the SDK supports one mounted
|
|
109
|
+
onboarding runtime at a time.
|
|
144
110
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
.getElementById('onboarding-container')
|
|
148
|
-
?.appendChild(onboardingApp.iframe);
|
|
111
|
+
The SDK 3 subpath remains available for consumers that need to pin the current package
|
|
112
|
+
boundary:
|
|
149
113
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
//Some logic here...
|
|
154
|
-
}
|
|
155
|
-
});
|
|
114
|
+
```ts
|
|
115
|
+
import { createWorthOnboarding } from '@worthai/onboarding-sdk/sdk3';
|
|
116
|
+
```
|
|
156
117
|
|
|
157
|
-
|
|
158
|
-
|
|
118
|
+
For script-tag usage, load the browser-global bundle from the package, then call
|
|
119
|
+
`window.WorthAI.createWorthOnboarding`:
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<script
|
|
123
|
+
src="https://unpkg.com/@worthai/onboarding-sdk@<version>/dist-sdk/sdk3/worthai-onboarding-sdk.global.js"
|
|
124
|
+
></script>
|
|
125
|
+
<script type="module">
|
|
126
|
+
const onboarding = window.WorthAI.createWorthOnboarding({
|
|
127
|
+
apiBaseUrl: 'https://api.example.com',
|
|
128
|
+
inviteToken: 'INVITE_TOKEN'
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await onboarding.mount('#worth-onboarding');
|
|
132
|
+
</script>
|
|
133
|
+
```
|
|
159
134
|
|
|
160
|
-
|
|
161
|
-
onboardingApp.next();
|
|
135
|
+
Build the deployed app and SDK artifacts separately:
|
|
162
136
|
|
|
163
|
-
|
|
164
|
-
|
|
137
|
+
```bash
|
|
138
|
+
pnpm build
|
|
139
|
+
pnpm build:sdk
|
|
165
140
|
```
|
|
166
141
|
|
|
167
|
-
|
|
142
|
+
`pnpm build` writes the deployable app to `dist/`. `pnpm build:sdk` writes
|
|
143
|
+
package artifacts to `dist-sdk/sdk3/` and does not replace the app `dist/`
|
|
144
|
+
output.
|
|
145
|
+
SDK artifacts are minified by default. For a local debug SDK build with readable
|
|
146
|
+
output and source maps, run:
|
|
168
147
|
|
|
169
|
-
```
|
|
170
|
-
|
|
148
|
+
```bash
|
|
149
|
+
WORTH_SDK_DEBUG=true pnpm build:sdk
|
|
150
|
+
```
|
|
171
151
|
|
|
172
|
-
|
|
173
|
-
|
|
152
|
+
## Folder Structure
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
.
|
|
156
|
+
|-- README.md
|
|
157
|
+
|-- react-vs-solid.README.md
|
|
158
|
+
|-- package.json
|
|
159
|
+
|-- vite.config.ts
|
|
160
|
+
|-- src/
|
|
161
|
+
| |-- App.tsx
|
|
162
|
+
| |-- index.tsx
|
|
163
|
+
| |-- routes.ts
|
|
164
|
+
| |-- routeDefinitions.ts
|
|
165
|
+
| |-- components/
|
|
166
|
+
| | |-- alerts/
|
|
167
|
+
| | |-- buttons/
|
|
168
|
+
| | |-- card/
|
|
169
|
+
| | |-- form/
|
|
170
|
+
| | | |-- modular/
|
|
171
|
+
| | | |-- inputs/
|
|
172
|
+
| | | |-- layoutContent/
|
|
173
|
+
| | | |-- widgets/
|
|
174
|
+
| | |-- global/
|
|
175
|
+
| | |-- icons/
|
|
176
|
+
| | |-- progress/
|
|
177
|
+
| | |-- step/
|
|
178
|
+
| |-- lib/
|
|
179
|
+
| | |-- axios/
|
|
180
|
+
| | |-- flowComposer/
|
|
181
|
+
| | | |-- componentRegistry/
|
|
182
|
+
| | | | |-- catalogs/
|
|
183
|
+
| | | |-- db/
|
|
184
|
+
| | | |-- flow/
|
|
185
|
+
| | | |-- form/
|
|
186
|
+
| | | |-- rules/
|
|
187
|
+
| | | |-- schema/
|
|
188
|
+
| | |-- google/
|
|
189
|
+
| | |-- storage/
|
|
190
|
+
| |-- pages/
|
|
191
|
+
| | |-- Composer/
|
|
192
|
+
| | | |-- editor/
|
|
193
|
+
| | | |-- steps/
|
|
194
|
+
| | |-- Login/
|
|
195
|
+
| |-- services/
|
|
196
|
+
| |-- auth/
|
|
197
|
+
| |-- case/
|
|
198
|
+
```
|
|
174
199
|
|
|
175
|
-
|
|
176
|
-
const subscription = consumerApp.subscribe((event) => {
|
|
177
|
-
if (event.data.type === 'NEXT_STAGE') {
|
|
178
|
-
// Add some logic here...
|
|
179
|
-
}
|
|
180
|
-
});
|
|
200
|
+
## Core FlowComposer Feature
|
|
181
201
|
|
|
182
|
-
|
|
183
|
-
|
|
202
|
+
`FlowComposer` is the schema-driven engine for the onboarding journey. It reads
|
|
203
|
+
the flow definition, resolves the current step, renders the matching UI
|
|
204
|
+
components, and manages step-to-step progression so forms can be updated by
|
|
205
|
+
changing configuration instead of rebuilding screens by hand.
|
|
184
206
|
|
|
185
|
-
|
|
186
|
-
onboardingConsumerApp.postMessage({
|
|
187
|
-
type: 'ROUTE_URL',
|
|
188
|
-
payload: { url: '/some-route-here' },
|
|
189
|
-
});
|
|
190
|
-
```
|
|
207
|
+
## Catalog Pattern
|
|
191
208
|
|
|
192
|
-
|
|
209
|
+
A catalog is the typed source of truth for what the schema is allowed to describe. In Flow Composer,
|
|
210
|
+
catalogs define supported field, layout, widget, and custom step types, including their metadata and
|
|
211
|
+
configuration schemas.
|
|
193
212
|
|
|
194
|
-
|
|
213
|
+
Catalogs do not render UI. They answer, "is this a valid thing the schema can ask for?"
|
|
195
214
|
|
|
196
|
-
|
|
215
|
+
## Registry Pattern
|
|
197
216
|
|
|
198
|
-
|
|
199
|
-
|
|
217
|
+
A registry maps known catalog entries to the renderer functions that produce UI at runtime. In Flow
|
|
218
|
+
Composer, the component registry takes validated schema items and resolves the field, layout, widget, or
|
|
219
|
+
step renderer that should handle each item.
|
|
200
220
|
|
|
201
|
-
|
|
202
|
-
origin: 'https://onboarding.example.com',
|
|
203
|
-
});
|
|
221
|
+
The catalog defines what exists. The registry decides how a known item becomes UI.
|
|
204
222
|
|
|
205
|
-
|
|
206
|
-
onboardingApp.postMessage({
|
|
207
|
-
type: 'SET_CUSTOM_CSS',
|
|
208
|
-
payload: {
|
|
209
|
-
css: `
|
|
210
|
-
body {
|
|
211
|
-
background: #f0f0f0;
|
|
212
|
-
font-family: 'Custom Font', sans-serif;
|
|
213
|
-
}
|
|
214
|
-
.onboarding-container {
|
|
215
|
-
padding: 20px;
|
|
216
|
-
border-radius: 8px;
|
|
217
|
-
}
|
|
218
|
-
`,
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
```
|
|
223
|
+
## Flow Composer Routes
|
|
222
224
|
|
|
223
|
-
|
|
225
|
+
- `/flow`: Renders the current `schema.json` and reflects the flow experience users would see.
|
|
226
|
+
- `/flow/editor`: Admin-focused route with a Monaco editor attached to `StepContainer` for live schema editing.
|
|
224
227
|
|
|
225
|
-
|
|
226
|
-
import { createOnboardingConsumerApp } from '@worthai/onboarding-sdk';
|
|
228
|
+
## Route Params: `:formKey` and `:stepKey`
|
|
227
229
|
|
|
228
|
-
|
|
230
|
+
Flow routes include dynamic params to identify what should be rendered:
|
|
229
231
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (event.data.type === 'SET_CUSTOM_CSS') {
|
|
233
|
-
// Create or update a style element
|
|
234
|
-
let styleElement = document.getElementById('custom-css-injection');
|
|
232
|
+
- `:formKey` identifies which form definition is active.
|
|
233
|
+
- `:stepKey` identifies the specific step within that form.
|
|
235
234
|
|
|
236
|
-
|
|
237
|
-
styleElement = document.createElement('style');
|
|
238
|
-
styleElement.id = 'custom-css-injection';
|
|
239
|
-
document.head.appendChild(styleElement);
|
|
240
|
-
}
|
|
235
|
+
Example pattern:
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
styleElement.innerHTML = event.data.payload.css;
|
|
244
|
-
}
|
|
245
|
-
});
|
|
237
|
+
`/flow/:formKey/:stepKey`
|
|
246
238
|
|
|
247
|
-
|
|
248
|
-
// subscription.unsubscribe();
|
|
249
|
-
```
|
|
239
|
+
Example concrete URL:
|
|
250
240
|
|
|
251
|
-
|
|
241
|
+
`/flow/company-info/get-started`
|
|
252
242
|
|
|
253
|
-
|
|
243
|
+
In practice, these params let the app deep-link to a specific form and step,
|
|
244
|
+
and are what flow navigation uses to move between steps in a predictable way.
|
|
254
245
|
|
|
255
|
-
|
|
246
|
+
### Current Limitation
|
|
256
247
|
|
|
257
|
-
|
|
258
|
-
-
|
|
248
|
+
The editor currently does not write changes back to files. Any live schema
|
|
249
|
+
edits in `/flow/editor` are in-memory only and will be lost on page refresh
|
|
250
|
+
until persistence is implemented.
|
|
259
251
|
|
|
260
|
-
##
|
|
252
|
+
## Application Tech Stack
|
|
261
253
|
|
|
262
|
-
|
|
254
|
+
| Technology | Purpose |
|
|
255
|
+
| --- | --- |
|
|
256
|
+
| [`solid-js`](https://docs.solidjs.com/) | Provides the reactive UI framework used to build the application. |
|
|
257
|
+
| [`@solidjs/router`](https://docs.solidjs.com/solid-router) | Handles client-side routing for the Solid application. |
|
|
258
|
+
| [`@solid-primitives/utils`](https://primitives.solidjs.community/package/utils/) | Provides shared utility helpers that complement Solid's reactive primitives. |
|
|
259
|
+
| [`@modular-forms/solid`](https://modularforms.dev/) | Provides form state management and validation helpers for Solid components. |
|
|
260
|
+
| [`vite`](https://vite.dev/guide/) | Provides the development server and production build tooling for the app. |
|
|
261
|
+
| [`typescript`](https://www.typescriptlang.org/docs/) | Adds static typing and compile-time checks for the application code. |
|
|
262
|
+
| [`@biomejs/biome`](https://biomejs.dev/) | Provides code formatting and linting to keep the codebase consistent. |
|
|
263
|
+
| [`markdownlint-cli2`](https://github.com/DavidAnson/markdownlint-cli2) | Runs markdown linting and automatic fixes for project documentation. |
|
|
264
|
+
| [`tailwindcss`](https://tailwindcss.com/docs) | Provides utility-first CSS classes for styling the application. |
|
|
265
|
+
| [`daisyui`](https://daisyui.com/) | Adds Tailwind CSS component classes and themes for faster UI development. |
|
|
266
|
+
| [`tailwind-merge`](https://github.com/dcastil/tailwind-merge) | Resolves conflicting Tailwind CSS classes when composing class strings. |
|
|
267
|
+
| [`@fontsource/figtree`](https://fontsource.org/fonts/figtree) | Provides the Figtree font as an installable package for application styling. |
|
|
268
|
+
| [`axios`](https://axios-http.com/docs/intro) | Handles HTTP requests to backend services and external APIs. |
|
|
269
|
+
| [`axios-retry`](https://github.com/softonic/axios-retry) | Adds retry behavior to Axios requests for transient network or service failures. |
|
|
270
|
+
| [`dexie`](https://dexie.org/docs/) | Provides a friendly IndexedDB wrapper for local browser storage. |
|
|
271
|
+
| [`zod`](https://zod.dev/) | Defines and validates runtime schemas for application data. |
|
|
272
|
+
| [`jsonc-parser`](https://github.com/microsoft/node-jsonc-parser) | Parses and edits JSON with comments for configuration-like content. |
|
|
273
|
+
| [`lodash`](https://lodash.com/docs/) | Provides general-purpose utility functions for working with collections, objects, and values. |
|
|
274
|
+
| [`libphonenumber-js`](https://gitlab.com/catamphetamine/libphonenumber-js) | Parses, formats, and validates phone numbers. |
|
|
275
|
+
| [`@googlemaps/js-api-loader`](https://googlemaps.github.io/js-api-loader/) | Loads the Google Maps JavaScript API on demand from application code. |
|
|
276
|
+
| [`@googlemaps/places`](https://www.npmjs.com/package/@googlemaps/places) | Provides Google Places API client utilities and types for place-related features. |
|
|
277
|
+
| [`monaco-editor`](https://microsoft.github.io/monaco-editor/) | Provides the browser-based code editor used for rich editing experiences. |
|
|
278
|
+
| [`monaco-json`](https://github.com/microsoft/monaco-json) | Adds JSON language support and validation features to Monaco editor. |
|
|
263
279
|
|
|
264
|
-
|
|
265
|
-
pnpm build
|
|
266
|
-
```
|
|
280
|
+
## Why SolidJS
|
|
267
281
|
|
|
268
|
-
|
|
282
|
+
SolidJS was chosen over React because of its fine-grained reactivity model. React relies on repeated component renders,
|
|
283
|
+
meaning each state change can trigger broader recalculation across the component tree.
|
|
269
284
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
```
|
|
285
|
+
In contrast, Solid updates only the exact reactive nodes that depend on a changed value.
|
|
286
|
+
There is no full component re-execution; only the minimal set of dependent expressions re-run.
|
|
273
287
|
|
|
274
|
-
|
|
288
|
+
This distinction is core to the architecture. Flow Composer is highly dynamic, and its performance and
|
|
289
|
+
predictability depend on updating only what actually changed. Solid's reactive model maps directly to that
|
|
290
|
+
requirement, making it a better fit for this system.
|
|
275
291
|
|
|
276
|
-
|
|
292
|
+
For deeper SolidJS reading, see [`react-vs-solid.README.md`](react-vs-solid.README.md) and
|
|
293
|
+
[Solid.js Best Practices](https://www.brenelz.com/posts/solid-js-best-practices/).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const WorthOnboardingErrorCode: {
|
|
2
|
+
readonly ALREADY_MOUNTED: "ALREADY_MOUNTED";
|
|
3
|
+
readonly CALLBACK_FAILED: "CALLBACK_FAILED";
|
|
4
|
+
readonly INVALID_MOUNT_TARGET: "INVALID_MOUNT_TARGET";
|
|
5
|
+
readonly INVALID_OPTIONS: "INVALID_OPTIONS";
|
|
6
|
+
readonly MISSING_INVITE_TOKEN: "MISSING_INVITE_TOKEN";
|
|
7
|
+
readonly MOUNT_CANCELLED: "MOUNT_CANCELLED";
|
|
8
|
+
readonly MOUNT_IN_PROGRESS: "MOUNT_IN_PROGRESS";
|
|
9
|
+
readonly MOUNT_TARGET_NOT_FOUND: "MOUNT_TARGET_NOT_FOUND";
|
|
10
|
+
readonly RUNTIME_ERROR: "RUNTIME_ERROR";
|
|
11
|
+
readonly RUNTIME_RENDER_FAILED: "RUNTIME_RENDER_FAILED";
|
|
12
|
+
readonly UNMOUNT_FAILED: "UNMOUNT_FAILED";
|
|
13
|
+
};
|
|
14
|
+
export type WorthOnboardingErrorCode = (typeof WorthOnboardingErrorCode)[keyof typeof WorthOnboardingErrorCode];
|
|
15
|
+
export interface WorthOnboardingErrorOptions {
|
|
16
|
+
readonly cause?: unknown;
|
|
17
|
+
readonly details?: Readonly<Record<string, unknown>>;
|
|
18
|
+
}
|
|
19
|
+
export declare class WorthOnboardingError extends Error {
|
|
20
|
+
readonly code: WorthOnboardingErrorCode;
|
|
21
|
+
readonly details?: Readonly<Record<string, unknown>>;
|
|
22
|
+
constructor(code: WorthOnboardingErrorCode, message: string, options?: WorthOnboardingErrorOptions);
|
|
23
|
+
}
|
|
24
|
+
export declare function isWorthOnboardingError(error: unknown): error is WorthOnboardingError;
|