@funnelsgrove/runtime 0.1.44 → 0.1.45
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 +44 -39
- package/dist/index.js +5 -0
- package/dist/runtime/posthog-flags.d.ts +1 -0
- package/dist/runtime/posthog-flags.js +12 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,60 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
Shared funnel runtime contracts and helpers.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Read this file before editing shared funnel mechanics. Deeper runtime behavior is
|
|
6
|
+
documented in [`docs/product-specs/funnel-template-runtime.md`](../../docs/product-specs/funnel-template-runtime.md).
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- The build normalizes generated relative ESM imports to explicit `.js` files for published package consumers.
|
|
8
|
+
## Owns funnel mechanics
|
|
9
|
+
|
|
10
|
+
`@funnelsgrove/runtime` owns the reusable mechanics that every generated or published funnel depends on: manifests, routing, env resolution, funnel state, preview/runtime detection, and generic runtime UI. Funnels bring their own copy, visual design, billing catalog, and step JSX.
|
|
11
11
|
|
|
12
12
|
## Use This Package For
|
|
13
13
|
|
|
14
14
|
- manifest types and validation
|
|
15
15
|
- route resolution and entry-point handling
|
|
16
|
+
- runtime mode and public env/config resolution
|
|
16
17
|
- experiment assignment helpers
|
|
17
18
|
- preview-bridge parsing and preview/runtime detection
|
|
18
19
|
- published theme contract and CSS variable helpers
|
|
19
|
-
- funnel context,
|
|
20
|
-
-
|
|
20
|
+
- funnel context, flow controller, and generic runtime UI primitives
|
|
21
|
+
- funnel-scoped state/storage helpers
|
|
21
22
|
- browser-safe API client helpers used by funnels
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- subscription handoff link rendering for iOS, Android, and desktop/web fallbacks from runtime env
|
|
43
|
-
- subscription handoff browser-only values are resolved after mount so published success routes hydrate without text mismatches
|
|
44
|
-
- public subscription summaries with provider plan and period metadata for funnel-local management screens
|
|
45
|
-
- a bottom-right `RuntimeDevInfoBox` that funnels can mount in test mode to inspect public runtime config with one canonical env/config name per row, copy the current funnel user id/email, switch to live mode, and clear funnel-scoped paywall state
|
|
23
|
+
- subscription handoff and subscription management screens whose copy stays funnel-local
|
|
24
|
+
- test-mode developer info surfaces for funnel preview tooling
|
|
25
|
+
|
|
26
|
+
## Do Not Use This Package For
|
|
27
|
+
|
|
28
|
+
- funnel-specific step JSX
|
|
29
|
+
- brand/theme assets
|
|
30
|
+
- billing catalog data
|
|
31
|
+
- analytics transport
|
|
32
|
+
- Stripe checkout UI
|
|
33
|
+
- funnel-specific developer widget copy
|
|
34
|
+
- direct provider SDK calls
|
|
35
|
+
|
|
36
|
+
## Public Surfaces
|
|
37
|
+
|
|
38
|
+
- `config/*`: manifest, theme, font, env, and builder-preview contracts.
|
|
39
|
+
- `runtime/*`: flow, routing, attribution, feature flags, preview bridge, URL attributes, and manifest validation.
|
|
40
|
+
- `services/*`: API client, runtime mode, public env, project env, logger, and funnel state helpers.
|
|
41
|
+
- `components/*`: generic runtime context, subscription handoff/management, editor panel, dev info, and base controls.
|
|
42
|
+
- `content/*` and `steps/types`: shared step content and taxonomy contracts.
|
|
46
43
|
|
|
47
44
|
## Storage Conventions
|
|
48
45
|
|
|
49
46
|
- runtime user ids stay funnel-scoped under `funnel:<funnelId>:user-id`
|
|
50
47
|
- runtime-generated user ids use the `u_` prefix
|
|
51
48
|
- paywall state is stored through runtime helpers under `fg_state:<funnelId>`
|
|
52
|
-
- developer reset controls should clear paywall state through `clearPaywallStateValue`, including
|
|
49
|
+
- developer reset controls should clear paywall state through `clearPaywallStateValue`, including funnel-provided compatibility keys when a live funnel still needs them
|
|
53
50
|
|
|
54
|
-
##
|
|
51
|
+
## Engineering Rules
|
|
55
52
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
- Do not import `@funnelsgrove/payments` or `@funnelsgrove/analytics` here for checkout or transport orchestration.
|
|
54
|
+
- Runtime UI must be generic and copy-injectable.
|
|
55
|
+
- Browser-only values must resolve after mount when SSR hydration can be affected.
|
|
56
|
+
- Keep env mapping centralized in `config/env.config.ts`.
|
|
57
|
+
|
|
58
|
+
## Build, Test, Publish
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run test:run --workspace @funnelsgrove/runtime
|
|
62
|
+
npm run build --workspace @funnelsgrove/runtime
|
|
63
|
+
npm publish --workspace @funnelsgrove/runtime --access public
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The build normalizes generated relative ESM imports to explicit `.js` files for published package consumers.
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
// Shared config contracts.
|
|
1
2
|
export * from './config/builder-preview.protocol.js';
|
|
2
3
|
export * from './config/env.config.js';
|
|
3
4
|
export * from './config/funnel.manifest.types.js';
|
|
4
5
|
export * from './config/funnel.experiments.types.js';
|
|
5
6
|
export * from './config/funnel-theme.js';
|
|
6
7
|
export * from './config/font-config.js';
|
|
8
|
+
// Structured content contracts.
|
|
7
9
|
export * from './content/step-content.js';
|
|
10
|
+
// Runtime mechanics.
|
|
8
11
|
export * from './runtime/experiment-assignment.js';
|
|
9
12
|
export * from './runtime/browser-helpers.js';
|
|
10
13
|
export * from './runtime/funnel-flow.js';
|
|
@@ -20,6 +23,7 @@ export * from './runtime/route-resolver.js';
|
|
|
20
23
|
export * from './runtime/subscription-handoff.js';
|
|
21
24
|
export * from './runtime/url-user-attributes.js';
|
|
22
25
|
export * from './runtime/use-url-user-attributes-sync.js';
|
|
26
|
+
// Browser-safe services.
|
|
23
27
|
export * from './services/api.service.js';
|
|
24
28
|
export * from './services/funnel-state.service.js';
|
|
25
29
|
export * from './services/logger.js';
|
|
@@ -28,6 +32,7 @@ export * from './services/project-env.js';
|
|
|
28
32
|
export * from './services/public-env.js';
|
|
29
33
|
export * from './services/runtime-api.config.js';
|
|
30
34
|
export * from './services/runtime-mode.service.js';
|
|
35
|
+
// SDK and generic runtime UI.
|
|
31
36
|
export * from './sdk/userAnswers.js';
|
|
32
37
|
export * from './components/FunnelContext.js';
|
|
33
38
|
export * from './components/FunnelEditorPanel.js';
|
|
@@ -3,6 +3,7 @@ import { runtimePublicConfig } from '../services/public-env.js';
|
|
|
3
3
|
let initialized = false;
|
|
4
4
|
let readyPromise = null;
|
|
5
5
|
export const POSTHOG_FEATURE_FLAG_READY_TIMEOUT_MS = 2500;
|
|
6
|
+
export const POSTHOG_SCOPED_FLAG_RELOAD_RETRY_MS = 300;
|
|
6
7
|
const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties';
|
|
7
8
|
const buildFlagScopeProperties = (config) => {
|
|
8
9
|
var _a, _b;
|
|
@@ -84,7 +85,17 @@ export const bootstrapPostHog = (config) => {
|
|
|
84
85
|
bootstrap: { distinctID: config.distinctId },
|
|
85
86
|
loaded: () => {
|
|
86
87
|
let unsubscribe = null;
|
|
87
|
-
|
|
88
|
+
let scopedReloadRetried = false;
|
|
89
|
+
unsubscribe = posthog.onFeatureFlags((flags) => {
|
|
90
|
+
if (Object.keys(scopeProperties).length > 0 &&
|
|
91
|
+
flags.length === 0 &&
|
|
92
|
+
!scopedReloadRetried) {
|
|
93
|
+
scopedReloadRetried = true;
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
posthog.reloadFeatureFlags();
|
|
96
|
+
}, POSTHOG_SCOPED_FLAG_RELOAD_RETRY_MS);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
88
99
|
unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe();
|
|
89
100
|
markReady();
|
|
90
101
|
});
|