@stnd/core 0.24.37 → 0.24.39
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 +39 -21
- package/package.json +6 -6
- package/src/loader.js +24 -9
package/README.md
CHANGED
|
@@ -61,11 +61,11 @@ The concept relies on a strict separation between the **Core** (static, tested)
|
|
|
61
61
|
|
|
62
62
|
---
|
|
63
63
|
|
|
64
|
-
##
|
|
64
|
+
## Module System (Spores)
|
|
65
65
|
|
|
66
66
|
Modules are auto-discovered and orchestrate both logic and interface via a **Unified Hooks** system.
|
|
67
67
|
|
|
68
|
-
### Anatomy of a
|
|
68
|
+
### Anatomy of a Module (`index.module.js`)
|
|
69
69
|
|
|
70
70
|
```javascript
|
|
71
71
|
export default {
|
|
@@ -87,21 +87,40 @@ export default {
|
|
|
87
87
|
};
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
### Virtual Modules & Rendering
|
|
90
|
+
### Virtual Modules & Rendering
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
- `virtual:stnd/components`: Used by the `<Hook />` component for UI rendering, and read directly (`extensions[zone]`) by client code that needs callable functions, not just components — e.g. `launcher:action`/`graft:action` entries.
|
|
92
|
+
The module loader compiles `hooks:` registrations into two dedicated virtual modules based on entry classification:
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
| Virtual Module | Entry Classification | Primary Consumers |
|
|
95
|
+
| :--- | :--- | :--- |
|
|
96
|
+
| `virtual:stnd/hooks` | **Logic hooks** — `.js` / `.ts` entries (excluding `launcher:*` and `*:action`) | `runHook()` and `runPipeline()` |
|
|
97
|
+
| `virtual:stnd/components` | **UI & action zones** — `.astro` / `.svelte` / `.md` components, plus all `launcher:*` and `*:action` entries | `<Hook zone="..." />` and `extensions[zone]` |
|
|
98
|
+
|
|
99
|
+
#### Calling Conventions (`virtual:stnd/hooks`)
|
|
100
|
+
|
|
101
|
+
- **Fan-out (`runHook(name, ...args)`)**: Calls every registered handler for `name` and collects their return values into an array (e.g. `astro:build:done`, `stnd:rss:register`).
|
|
102
|
+
- **Sequential Pipeline (`runPipeline(name, initialValue, ...args)`)**: Threads a single value through every registered handler in sequence. Each handler must explicitly return the (optionally transformed) value — ideal when modules inspect and override a shared descriptor (e.g. `note:render` in `apps/stnd.gd`).
|
|
103
|
+
|
|
104
|
+
#### Isolation & Bundling Guarantees
|
|
105
|
+
|
|
106
|
+
- **Failure Isolation**: Both `runHook` and `runPipeline` isolate handler exceptions — a throwing handler is logged and skipped so it cannot abort sibling handlers.
|
|
107
|
+
- **Server-Only Filtering (`server: true`)**: Handlers marked with `server: true` are stripped from the client bundle of `virtual:stnd/hooks`. Use this for any handler touching databases or secrets when client modules (like `@stnd/launcher`) also import from `virtual:stnd/hooks`.
|
|
108
|
+
- **Build-Time Classification Guards**:
|
|
109
|
+
- Registering the same hook name as both a logic hook and a UI/action zone across modules throws a build-time fatal error ([`hook-kind-mismatch`](https://stnd.build/manual/diagnostic/hook-kind-mismatch)).
|
|
110
|
+
- Setting `server: true` on a `launcher:*` or `*:action` entry throws a build-time fatal error ([`hook-server-flag-ignored`](https://stnd.build/manual/diagnostic/hook-server-flag-ignored)), since `virtual:stnd/components` has no SSR/client split.
|
|
111
|
+
|
|
112
|
+
#### UI Consumption
|
|
96
113
|
|
|
97
114
|
```astro
|
|
115
|
+
---
|
|
98
116
|
import Hook from "@stnd/core/Hook.astro";
|
|
99
|
-
|
|
117
|
+
---
|
|
118
|
+
<Hook zone="header:top" />
|
|
100
119
|
```
|
|
101
120
|
|
|
102
121
|
---
|
|
103
122
|
|
|
104
|
-
##
|
|
123
|
+
## Helpers Reference (Core & Server)
|
|
105
124
|
|
|
106
125
|
Importable via `@stnd/server/[filename]` or `@stnd/utils/[filename]`.
|
|
107
126
|
|
|
@@ -140,7 +159,7 @@ Importable via `@stnd/server/[filename]` or `@stnd/utils/[filename]`.
|
|
|
140
159
|
| `getReadingTime` | `getReadingTime(text)` | Estimated reading time. |
|
|
141
160
|
| `validateEmail` | `validateEmail(email)` | Simplified email validation. |
|
|
142
161
|
|
|
143
|
-
### Other Helpers
|
|
162
|
+
### Other Helpers
|
|
144
163
|
|
|
145
164
|
- `@stnd/server/cors.js`: `getCorsHeaders`, `handleCorsPreflight`.
|
|
146
165
|
- `@stnd/server/errors.js`: Standardized error classes (`StandardError`, `AuthError`, etc.).
|
|
@@ -150,11 +169,11 @@ Importable via `@stnd/server/[filename]` or `@stnd/utils/[filename]`.
|
|
|
150
169
|
|
|
151
170
|
---
|
|
152
171
|
|
|
153
|
-
##
|
|
172
|
+
## Design Tokens (CSS Variables)
|
|
154
173
|
|
|
155
174
|
The system uses CSS variables (`--stnd-*` or root variables `:root`) for consistency.
|
|
156
175
|
|
|
157
|
-
###
|
|
176
|
+
### Geometry & Rhythm (`packages/styles/_standard-01-token.scss`)
|
|
158
177
|
|
|
159
178
|
| Variable | Default Value | Description |
|
|
160
179
|
| :--- | :--- | :--- |
|
|
@@ -170,7 +189,7 @@ The system uses CSS variables (`--stnd-*` or root variables `:root`) for consist
|
|
|
170
189
|
| `--rhythm-block-scale` | `2` | Multiplier for non-text block elements. |
|
|
171
190
|
| `--radius` | `--leading` | Border radius consistent with rhythm. |
|
|
172
191
|
|
|
173
|
-
###
|
|
192
|
+
### Colors (`packages/styles/_standard-02-color.scss`)
|
|
174
193
|
|
|
175
194
|
OKLCH-based system generating harmony from `--color-accent`.
|
|
176
195
|
|
|
@@ -184,7 +203,7 @@ OKLCH-based system generating harmony from `--color-accent`.
|
|
|
184
203
|
| `--color-[green\|red\|yellow\|blue]` | Pigment colors derived from accent. |
|
|
185
204
|
| `--color-success\|error\|warning` | Semantic states. |
|
|
186
205
|
|
|
187
|
-
###
|
|
206
|
+
### SCSS Breakpoints
|
|
188
207
|
|
|
189
208
|
- `$mobile`: 600px
|
|
190
209
|
- `$small`: 768px
|
|
@@ -193,7 +212,7 @@ OKLCH-based system generating harmony from `--color-accent`.
|
|
|
193
212
|
|
|
194
213
|
---
|
|
195
214
|
|
|
196
|
-
##
|
|
215
|
+
## Notes for AI
|
|
197
216
|
|
|
198
217
|
- **Module Integration**: Standardized on *“Module”* terminology (formerly Folios/Spores).
|
|
199
218
|
- **Actions**: Core actions are now fully decanted into their respective modules and aggregated via `virtual:stnd/actions`.
|
|
@@ -223,11 +242,10 @@ Part of the [Road to Public Release](../README.md#-road-to-public-release) (Phas
|
|
|
223
242
|
- [ ] **`adeSsrDeps` → `@stnd/cloudflare`** (not core) — decided during Phase 2: [priority:: 3] [token_scale:: 3] [created:: 2026-07-14] [area:: framework]
|
|
224
243
|
the SSR/workerd optimizeDeps fix belongs with the Cloudflare package, split from the app-specific deps that stay in the app.
|
|
225
244
|
|
|
226
|
-
##
|
|
245
|
+
## Links & Standards
|
|
227
246
|
|
|
228
|
-
|
|
229
|
-
- **Architecture
|
|
230
|
-
- **
|
|
231
|
-
- **
|
|
232
|
-
- **
|
|
233
|
-
- **Entrée Monorepo** : [README.md](../../README.md)
|
|
247
|
+
This package implements the core architectural principles of the Standard ecosystem. For further details on how the framework operates globally, see:
|
|
248
|
+
- **System Architecture**: [Framework Guide & Invariants](../../apps/stnd.build/modules/manual/content/system/framework-guide.md)
|
|
249
|
+
- **Engineering Philosophy**: [Engineering Philosophy](../../apps/stnd.build/modules/manual/content/philosophy/engineering-philosophy.md)
|
|
250
|
+
- **Package Ecosystem**: [packages/README.md](../README.md)
|
|
251
|
+
- **Monorepo Root**: [README.md](../../README.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stnd/core",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.39",
|
|
4
4
|
"description": "A fine-art typography framework implementing classical design principles, mathematical precision with the golden ratio, and micro-typography rules inspired by the masters of print design.",
|
|
5
5
|
"author": "Francis Fontaine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,17 +61,17 @@
|
|
|
61
61
|
"@stnd/cloudflare": "0.8.2",
|
|
62
62
|
"@stnd/fonts": "0.8.1",
|
|
63
63
|
"@stnd/icon": "0.10.0",
|
|
64
|
-
"@stnd/lab": "1.6.1",
|
|
65
64
|
"@stnd/client": "0.7.8",
|
|
66
|
-
"@stnd/
|
|
67
|
-
"@stnd/layout": "0.10.1",
|
|
65
|
+
"@stnd/lab": "1.6.1",
|
|
68
66
|
"@stnd/log": "0.6.0",
|
|
69
|
-
"@stnd/modules": "0.
|
|
67
|
+
"@stnd/modules": "0.14.1",
|
|
70
68
|
"@stnd/press": "0.13.2",
|
|
71
69
|
"@stnd/store": "0.6.0",
|
|
72
70
|
"@stnd/styles": "0.27.2",
|
|
73
|
-
"@stnd/themes": "0.26.
|
|
71
|
+
"@stnd/themes": "0.26.5",
|
|
74
72
|
"@stnd/ui": "0.16.1",
|
|
73
|
+
"@stnd/layout": "0.10.1",
|
|
74
|
+
"@stnd/launcher": "1.10.2",
|
|
75
75
|
"@stnd/utils": "0.10.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
package/src/loader.js
CHANGED
|
@@ -129,19 +129,33 @@ export async function loadModules({
|
|
|
129
129
|
log.success("Initializing module engine...");
|
|
130
130
|
|
|
131
131
|
const modulePatterns = buildModulePatterns(finalConfig);
|
|
132
|
-
const
|
|
132
|
+
const coreRequire = createRequire(import.meta.url);
|
|
133
|
+
let appRequire = coreRequire;
|
|
134
|
+
try {
|
|
135
|
+
appRequire = createRequire(path.join(appRoot, "package.json"));
|
|
136
|
+
} catch {
|
|
137
|
+
// Fallback to coreRequire when appRoot has no package.json
|
|
138
|
+
}
|
|
133
139
|
|
|
134
140
|
const discoveredFiles = discoverModuleFiles(appRoot, modulePatterns);
|
|
135
141
|
|
|
136
|
-
const resolveModulePath = (idOrPath) => {
|
|
142
|
+
const resolveModulePath = (idOrPath, fromFile = null) => {
|
|
137
143
|
if (path.isAbsolute(idOrPath)) return idOrPath;
|
|
138
144
|
|
|
139
145
|
const tryResolve = (id) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
for (const req of [
|
|
147
|
+
appRequire,
|
|
148
|
+
fromFile ? createRequire(fromFile) : null,
|
|
149
|
+
coreRequire,
|
|
150
|
+
]) {
|
|
151
|
+
if (!req) continue;
|
|
152
|
+
try {
|
|
153
|
+
return req.resolve(id);
|
|
154
|
+
} catch {
|
|
155
|
+
// try next resolver
|
|
156
|
+
}
|
|
144
157
|
}
|
|
158
|
+
return null;
|
|
145
159
|
};
|
|
146
160
|
|
|
147
161
|
const isBare =
|
|
@@ -175,8 +189,8 @@ export async function loadModules({
|
|
|
175
189
|
while (loadQueue.length > 0) {
|
|
176
190
|
const batch = loadQueue.splice(0, loadQueue.length);
|
|
177
191
|
const tasks = batch
|
|
178
|
-
.map(({ rawId, origin, sourceModule }) => {
|
|
179
|
-
const resolvedPath = resolveModulePath(rawId);
|
|
192
|
+
.map(({ rawId, origin, sourceModule, sourceFile }) => {
|
|
193
|
+
const resolvedPath = resolveModulePath(rawId, sourceFile);
|
|
180
194
|
if (!resolvedPath || processedPaths.has(resolvedPath)) return null;
|
|
181
195
|
processedPaths.add(resolvedPath);
|
|
182
196
|
return { rawId, origin, sourceModule, resolvedPath };
|
|
@@ -254,6 +268,7 @@ export async function loadModules({
|
|
|
254
268
|
rawId: depId,
|
|
255
269
|
origin: "dependency",
|
|
256
270
|
sourceModule: def.id,
|
|
271
|
+
sourceFile: resolvedPath,
|
|
257
272
|
});
|
|
258
273
|
}
|
|
259
274
|
}
|
|
@@ -281,7 +296,7 @@ export async function loadModules({
|
|
|
281
296
|
for (const rawDep of def.dependencies) {
|
|
282
297
|
let depId = rawDep;
|
|
283
298
|
if (!idToPath.has(depId)) {
|
|
284
|
-
const resolvedDepPath = resolveModulePath(rawDep);
|
|
299
|
+
const resolvedDepPath = resolveModulePath(rawDep, pathStr);
|
|
285
300
|
if (resolvedDepPath && moduleMap.has(resolvedDepPath)) {
|
|
286
301
|
depId = moduleMap.get(resolvedDepPath).def.id;
|
|
287
302
|
}
|