@morphika/andami 0.1.2 → 0.1.3

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.
@@ -1,57 +1,28 @@
1
- /**
1
+ /**
2
2
  * Site configuration accessor.
3
3
  *
4
- * Call `registerConfig(config)` at app startup (e.g. in your root layout)
5
- * before any component calls `getSiteConfig()`. The instance's
6
- * `app/layout.tsx` imports its own `site.config.ts` and passes it here.
4
+ * Uses globalThis + Symbol.for to guarantee a true singleton even when
5
+ * the bundler creates multiple module instances of this file.
7
6
  */
8
7
 
9
8
  import type { SiteConfig } from "./types";
10
9
 
11
- /** Module-level slot for the registered config. */
12
- let _registeredConfig: SiteConfig | null = null;
10
+ const CONFIG_KEY = Symbol.for("@morphika/andami/siteConfig");
11
+ const g = globalThis as unknown as Record<symbol, SiteConfig | undefined>;
13
12
 
14
- /** Cached reference. */
15
- let _resolved: SiteConfig | null = null;
16
-
17
- /**
18
- * Register the site configuration.
19
- *
20
- * Call this once at app startup (root layout module scope) before any
21
- * component or API route calls `getSiteConfig()`. The instance's
22
- * `app/layout.tsx` imports its own `site.config.ts` and passes it here.
23
- *
24
- * Calling this more than once replaces the previous config (useful for
25
- * testing, but not expected in production).
26
- */
27
13
  export function registerConfig(config: SiteConfig): void {
28
- _registeredConfig = config;
29
- // Invalidate resolved cache so next getSiteConfig() picks up the new value.
30
- _resolved = null;
14
+ g[CONFIG_KEY] = config;
31
15
  }
32
16
 
33
- /**
34
- * Get the site configuration.
35
- *
36
- * Returns the config registered via `registerConfig()`.
37
- * Throws if no config has been registered yet.
38
- *
39
- * Returns the same object reference on every call (singleton).
40
- * Safe to call from both server and client components.
41
- */
42
17
  export function getSiteConfig(): SiteConfig {
43
- if (!_resolved) {
44
- if (_registeredConfig) {
45
- _resolved = _registeredConfig;
46
- } else {
47
- throw new Error(
48
- "SiteConfig not registered. Call registerConfig(config) in your root layout before using getSiteConfig().\n" +
49
- "See: https://github.com/MorphikaStudio/Morphika_Andami#quick-start",
50
- );
51
- }
18
+ const cfg = g[CONFIG_KEY];
19
+ if (!cfg) {
20
+ throw new Error(
21
+ "SiteConfig not registered. Call registerConfig(config) in your root layout before using getSiteConfig().\n" +
22
+ "See: https://github.com/MorphikaStudio/Morphika_Andami#quick-start",
23
+ );
52
24
  }
53
- return _resolved;
25
+ return cfg;
54
26
  }
55
27
 
56
- // Re-export types for convenience
57
- export type { SiteConfig } from "./types";
28
+ export type { SiteConfig } from "./types";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morphika/andami",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Visual Page Builder — core library. A reusable website builder with visual editing, CMS integration, and asset management.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,7 +46,6 @@
46
46
  "exports": {
47
47
  "./config": "./lib/config/index.ts",
48
48
  "./config/types": "./lib/config/types.ts",
49
-
50
49
  "./components/blocks": "./components/blocks/index.ts",
51
50
  "./components/blocks/*": "./components/blocks/*.tsx",
52
51
  "./components/builder": "./components/builder/index.ts",
@@ -65,7 +64,6 @@
65
64
  "./components/admin/styles": "./components/admin/styles/index.ts",
66
65
  "./components/admin/styles/*": "./components/admin/styles/*.tsx",
67
66
  "./components/ui/*": "./components/ui/*.tsx",
68
-
69
67
  "./lib/builder": "./lib/builder/index.ts",
70
68
  "./lib/builder/*": "./lib/builder/*.ts",
71
69
  "./lib/sanity/client": "./lib/sanity/client.ts",
@@ -94,7 +92,6 @@
94
92
  "./lib/format-utils": "./lib/format-utils.ts",
95
93
  "./lib/utils": "./lib/utils.ts",
96
94
  "./lib/asset-retry": "./lib/asset-retry.ts",
97
-
98
95
  "./sanity/schemas": "./sanity/schemas/index.ts",
99
96
  "./sanity/schemas/*": "./sanity/schemas/*.ts",
100
97
  "./sanity/schemas/blocks": "./sanity/schemas/blocks/index.ts",
@@ -102,12 +99,10 @@
102
99
  "./sanity/schemas/objects/*": "./sanity/schemas/objects/*.ts",
103
100
  "./sanity/compose": "./sanity/compose.ts",
104
101
  "./sanity/config": "./sanity/sanity.config.ts",
105
-
106
102
  "./styles/base.css": "./styles/base.css",
107
103
  "./styles/animations.css": "./styles/animations.css",
108
104
  "./styles/admin.css": "./styles/admin.css",
109
105
  "./styles/globals.css": "./styles/globals.css",
110
-
111
106
  "./site": "./site/index.ts",
112
107
  "./site/page": "./site/page.ts",
113
108
  "./site/work": "./site/work.ts",
@@ -116,7 +111,6 @@
116
111
  "./site/error": "./site/error.ts",
117
112
  "./site/robots": "./site/robots.ts",
118
113
  "./site/sitemap": "./site/sitemap.ts",
119
-
120
114
  "./admin": "./admin/index.ts",
121
115
  "./admin/login": "./admin/login.ts",
122
116
  "./admin/pages": "./admin/pages.ts",
@@ -130,14 +124,10 @@
130
124
  "./admin/database": "./admin/database.ts",
131
125
  "./admin/settings": "./admin/settings.ts",
132
126
  "./admin/setup": "./admin/setup.ts",
133
-
134
127
  "./components/admin/setup-wizard": "./components/admin/setup-wizard/index.ts",
135
128
  "./components/admin/setup-wizard/*": "./components/admin/setup-wizard/*.tsx",
136
-
137
129
  "./lib/setup/detect": "./lib/setup/detect.ts",
138
-
139
130
  "./studio": "./studio/index.ts",
140
-
141
131
  "./api/admin/auth": "./app/api/admin/auth/route.ts",
142
132
  "./api/admin/pages": "./app/api/admin/pages/route.ts",
143
133
  "./api/admin/pages/slug": "./app/api/admin/pages/[slug]/route.ts",
package/styles/base.css CHANGED
@@ -1,17 +1,14 @@
1
- @import "tailwindcss";
2
-
3
- /* ============================================
1
+ /* ============================================
4
2
  Brand Design Tokens
5
3
  Values come from site.config.ts palette.
6
4
  Tailwind generates classes: bg-brand-*, text-brand-*, etc.
5
+
6
+ NOTE: @import "tailwindcss" is NOT included here.
7
+ Each instance must add it in their own globals.css BEFORE
8
+ importing this file.
7
9
  ============================================ */
8
10
 
9
11
  @theme inline {
10
- /* Brand Colors — semantic tokens.
11
- Initial values are neutral placeholders for Tailwind class generation.
12
- Actual colors are injected at runtime by StylesProvider from the admin
13
- palette, with site.config.ts palette as fallback.
14
- See lib/styles/provider.tsx → generateBrandTokens(). */
15
12
  --color-brand-accent: var(--brand-accent, #888888);
16
13
  --color-brand-accent-alt: var(--brand-accent-alt, #888888);
17
14
  --color-brand-secondary: var(--brand-secondary, #888888);
@@ -21,11 +18,9 @@
21
18
  --color-brand-muted: var(--brand-muted, #888888);
22
19
  --color-brand-dark: var(--brand-dark, #111111);
23
20
 
24
- /* Fonts — placeholders, overridden by StylesProvider */
25
21
  --font-mono: var(--brand-font-mono, ui-monospace, monospace);
26
22
  --font-sans: "Inter", system-ui, sans-serif;
27
23
 
28
- /* Breakpoints — matching original Semplice grid */
29
24
  --breakpoint-xs: 0px;
30
25
  --breakpoint-sm: 544px;
31
26
  --breakpoint-md: 768px;
@@ -33,20 +28,6 @@
33
28
  --breakpoint-xl: 1170px;
34
29
  }
35
30
 
36
- /* ============================================
37
- @font-face — Instance Default Font
38
- No hardcoded @font-face here. The default/fallback font is loaded
39
- by StylesProvider at runtime based on site.config.ts typography
40
- settings and admin-uploaded fonts. For the initial render before
41
- JS loads, the --font-mono stack in @theme provides the fallback.
42
- ============================================ */
43
-
44
- /* ============================================
45
- Admin UI Tokens
46
- Used across all builder/admin components.
47
- JS constants in lib/builder/constants.ts mirror these.
48
- ============================================ */
49
-
50
31
  :root {
51
32
  --admin-accent: #076bff;
52
33
  --admin-accent-dark: #0559d4;
@@ -56,10 +37,6 @@
56
37
  --admin-success: #22c55e;
57
38
  }
58
39
 
59
- /* ============================================
60
- Base styles
61
- ============================================ */
62
-
63
40
  html {
64
41
  scroll-behavior: smooth;
65
42
  overflow-x: clip;
@@ -72,21 +49,14 @@ body {
72
49
  font-family: var(--font-mono);
73
50
  overflow-x: clip;
74
51
  width: 100%;
75
- /* Smooth body bg transition when navigating between pages with different
76
- backgrounds. PageBackground component syncs this via inline style. */
77
52
  transition: background-color 300ms ease;
78
53
  }
79
54
 
80
- /* Public site wrapper:
81
- - overflow-x:clip prevents horizontal scroll (iOS WebKit fix, stricter than hidden)
82
- - max-width:100vw constrains all children to viewport width */
83
55
  [data-site] {
84
56
  max-width: 100vw;
85
57
  overflow-x: clip;
86
58
  }
87
59
 
88
- /* Custom cursor: hide native cursor when enabled via data attribute.
89
- Controlled by site.config.ts features.customCursor → site layout. */
90
60
  [data-custom-cursor] {
91
61
  cursor: none;
92
62
  }
@@ -96,37 +66,23 @@ body {
96
66
  cursor: none;
97
67
  }
98
68
 
99
- /* Restore cursor inside Sanity Studio */
100
69
  [data-sanity-studio], [data-sanity-studio] *, [data-ui], [data-ui] * {
101
70
  cursor: auto !important;
102
71
  }
103
72
 
104
- /* Selection color */
105
73
  ::selection {
106
74
  background: var(--color-brand-primary);
107
75
  color: var(--color-brand-text);
108
76
  }
109
77
 
110
- /* ============================================
111
- Failed Asset Placeholder
112
- Replaces the browser's broken image icon with a subtle,
113
- clickable placeholder that invites retry. Applied automatically
114
- by lib/asset-retry.ts after exhausting retries.
115
- ============================================ */
116
-
117
78
  img[data-asset-failed] {
118
- /* Hide the browser's broken image icon */
119
79
  color: transparent;
120
- /* Show a neutral placeholder background */
121
80
  background: linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 100%);
122
- /* Ensure it has visible dimensions even without intrinsic size */
123
81
  min-height: 60px;
124
82
  min-width: 60px;
125
- /* Position the "tap to retry" pseudo-element */
126
83
  position: relative;
127
84
  }
128
85
 
129
- /* "Tap to retry" overlay text — uses outline trick for pseudo on img */
130
86
  img[data-asset-failed]::after {
131
87
  content: "Tap to retry";
132
88
  position: absolute;
@@ -145,4 +101,4 @@ img[data-asset-failed]::after {
145
101
  video[data-asset-failed] {
146
102
  background: #1a1a1a;
147
103
  min-height: 60px;
148
- }
104
+ }