@instroc/client 1.0.0-alpha.1 → 1.0.0-alpha.4

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as zustand_vanilla from 'zustand/vanilla';
1
+ import * as zustand_vanilla from "zustand/vanilla";
2
2
 
3
3
  /**
4
4
  * Shared config consumed by every @instroc/* SDK package. Lives in a single
@@ -6,30 +6,30 @@ import * as zustand_vanilla from 'zustand/vanilla';
6
6
  * functions, and storage in one shot — no provider tree required.
7
7
  */
8
8
  interface InstrocConfig {
9
- /**
10
- * BaaS project id — required for any SDK call that hits the backend.
11
- * Null means the SDK is uninitialized; hooks return safe defaults
12
- * (logged-out / loading=false / no project) until set.
13
- */
14
- projectId: string | null;
15
- /**
16
- * Base URL the SDK appends `${projectId}/...` paths to.
17
- * Defaults to `/api/baas` so apps served behind the published-app router
18
- * just work.
19
- */
20
- baseUrl: string;
21
- /**
22
- * If true, auth persists the session in localStorage and rehydrates on
23
- * boot. Generated apps almost always want this; set false in tests or
24
- * embed contexts where you don't want the session to leak across runs.
25
- */
26
- persistSession: boolean;
27
- /**
28
- * Optional API key for server-to-server data calls. Null in browser apps
29
- * (auth is per-user via cookies/tokens). Reserved for SSR / Worker
30
- * scenarios that may show up post-launch.
31
- */
32
- apiKey: string | null;
9
+ /**
10
+ * BaaS project id — required for any SDK call that hits the backend.
11
+ * Null means the SDK is uninitialized; hooks return safe defaults
12
+ * (logged-out / loading=false / no project) until set.
13
+ */
14
+ projectId: string | null;
15
+ /**
16
+ * Base URL the SDK appends `${projectId}/...` paths to.
17
+ * Defaults to `/api/baas` so apps served behind the published-app router
18
+ * just work.
19
+ */
20
+ baseUrl: string;
21
+ /**
22
+ * If true, auth persists the session in localStorage and rehydrates on
23
+ * boot. Generated apps almost always want this; set false in tests or
24
+ * embed contexts where you don't want the session to leak across runs.
25
+ */
26
+ persistSession: boolean;
27
+ /**
28
+ * Optional API key for server-to-server data calls. Null in browser apps
29
+ * (auth is per-user via cookies/tokens). Reserved for SSR / Worker
30
+ * scenarios that may show up post-launch.
31
+ */
32
+ apiKey: string | null;
33
33
  }
34
34
  /**
35
35
  * Caller-supplied init shape. projectId is required; everything else has a
@@ -37,7 +37,7 @@ interface InstrocConfig {
37
37
  * forward-compatible — adding a new optional field never breaks callers.
38
38
  */
39
39
  interface InitInstrocOptions extends Partial<InstrocConfig> {
40
- projectId: string;
40
+ projectId: string;
41
41
  }
42
42
 
43
43
  /**
@@ -65,6 +65,52 @@ declare function initInstroc(options: InitInstrocOptions): void;
65
65
  * failures otherwise.
66
66
  */
67
67
  declare function resetInstroc(): void;
68
+ /**
69
+ * Auto-init from the build-server bootstrap contract.
70
+ *
71
+ * The Instroc build server injects this snippet into the generated
72
+ * `index.html` before any module scripts:
73
+ *
74
+ * <script>
75
+ * window.__INSTROC_BOOTSTRAP__ = {
76
+ * projectId: "...",
77
+ * baseUrl: "...",
78
+ * apiKey: "...",
79
+ * };
80
+ * </script>
81
+ *
82
+ * The SDK reads it on module load. No `process.env` substitution, no
83
+ * bundler-specific magic, no manual `initInstroc()` call from app code.
84
+ *
85
+ * Why a window global instead of `process.env`:
86
+ * - Bundler-agnostic — works under vite, webpack, esbuild, swc
87
+ * - Visible in view-source — debuggable in 2 seconds
88
+ * - Loud failure — if the build is wrong the global is missing and
89
+ * hooks can throw a clear error rather than silently sitting at
90
+ * loading=true forever
91
+ * - Easy to test — set the global before importing the module
92
+ *
93
+ * Module-script timing: classic `<script>` tags in `<head>` execute
94
+ * before any deferred module script (`<script type="module">`), so the
95
+ * global is set before this IIFE runs.
96
+ */
97
+ declare global {
98
+ interface Window {
99
+ __INSTROC_BOOTSTRAP__?: {
100
+ projectId?: unknown;
101
+ baseUrl?: unknown;
102
+ apiKey?: unknown;
103
+ };
104
+ }
105
+ }
106
+ /**
107
+ * Throw a clear error if the SDK is asked to do something that requires a
108
+ * configured projectId but auto-init never seeded one. Used by hooks that
109
+ * make network requests; lets the failure surface immediately instead of
110
+ * leaving the UI stuck at `loading: true` forever when the build server
111
+ * forgot to inject the bootstrap.
112
+ */
113
+ declare function assertInstrocConfigured(): void;
68
114
  /**
69
115
  * Read the current config synchronously. Use inside non-React code (event
70
116
  * handlers, fetch wrappers, the auth bootstrap effect). For React
@@ -96,4 +142,15 @@ declare function useInstrocConfig(): InstrocConfig;
96
142
  */
97
143
  declare function useInstrocReady(): boolean;
98
144
 
99
- export { type InitInstrocOptions, type InstrocConfig, configStore, getInstrocConfig, initInstroc, resetInstroc, setInstrocProjectId, useInstrocConfig, useInstrocReady };
145
+ export {
146
+ type InitInstrocOptions,
147
+ type InstrocConfig,
148
+ assertInstrocConfigured,
149
+ configStore,
150
+ getInstrocConfig,
151
+ initInstroc,
152
+ resetInstroc,
153
+ setInstrocProjectId,
154
+ useInstrocConfig,
155
+ useInstrocReady,
156
+ };
package/dist/index.js CHANGED
@@ -19,6 +19,33 @@ function initInstroc(options) {
19
19
  function resetInstroc() {
20
20
  configStore.setState({ ...DEFAULT_CONFIG }, true);
21
21
  }
22
+ (function autoInitFromBootstrap() {
23
+ const bootstrap = globalThis.__INSTROC_BOOTSTRAP__;
24
+ if (!bootstrap)
25
+ return;
26
+ const projectId = typeof bootstrap.projectId === "string" && bootstrap.projectId.length > 0 ? bootstrap.projectId : null;
27
+ if (!projectId) {
28
+ console.error(
29
+ "[Instroc] window.__INSTROC_BOOTSTRAP__ is set but missing a non-empty projectId. Check the build-server's index.html generation."
30
+ );
31
+ return;
32
+ }
33
+ const baseUrl = typeof bootstrap.baseUrl === "string" && bootstrap.baseUrl.length > 0 ? bootstrap.baseUrl : null;
34
+ const apiKey = typeof bootstrap.apiKey === "string" && bootstrap.apiKey.length > 0 ? bootstrap.apiKey : null;
35
+ configStore.setState((prev) => ({
36
+ ...prev,
37
+ projectId,
38
+ ...baseUrl ? { baseUrl } : {},
39
+ ...apiKey ? { apiKey } : {}
40
+ }));
41
+ })();
42
+ function assertInstrocConfigured() {
43
+ if (configStore.getState().projectId)
44
+ return;
45
+ throw new Error(
46
+ "Instroc SDK not configured. Expected `window.__INSTROC_BOOTSTRAP__` to be set by the build server before the app loads, or `initInstroc({ projectId })` to be called manually in tests / multi-tenant setups."
47
+ );
48
+ }
22
49
  function getInstrocConfig() {
23
50
  return configStore.getState();
24
51
  }
@@ -40,6 +67,7 @@ function useInstrocReady() {
40
67
  );
41
68
  }
42
69
  export {
70
+ assertInstrocConfigured,
43
71
  configStore,
44
72
  getInstrocConfig,
45
73
  initInstroc,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instroc/client",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.4",
4
4
  "description": "Shared config store for Instroc Cloud SDK packages — initInstroc(), useInstrocConfig(), and the singleton store consumed by @instroc/auth, @instroc/data, @instroc/functions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -14,10 +14,6 @@
14
14
  "files": [
15
15
  "dist"
16
16
  ],
17
- "scripts": {
18
- "build": "tsup",
19
- "dev": "tsup --watch"
20
- },
21
17
  "peerDependencies": {
22
18
  "react": "^18.0.0 || ^19.0.0"
23
19
  },
@@ -36,5 +32,9 @@
36
32
  },
37
33
  "publishConfig": {
38
34
  "access": "public"
35
+ },
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "dev": "tsup --watch"
39
39
  }
40
- }
40
+ }