stonyx 0.2.3-alpha.8 → 0.2.3-alpha.80

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.
Files changed (71) hide show
  1. package/README.md +32 -7
  2. package/config/{environment.js → environment copy.ts } +16 -12
  3. package/dist/cli/help.d.ts +8 -0
  4. package/dist/cli/help.js +43 -0
  5. package/dist/cli/load-commands.d.ts +10 -0
  6. package/dist/cli/load-commands.js +49 -0
  7. package/dist/cli/new.d.ts +72 -0
  8. package/dist/cli/new.js +422 -0
  9. package/dist/cli/serve.d.ts +6 -0
  10. package/dist/cli/serve.js +49 -0
  11. package/dist/cli/test-setup.d.ts +1 -0
  12. package/dist/cli/test-setup.js +30 -0
  13. package/dist/cli/test.d.ts +4 -0
  14. package/dist/cli/test.js +23 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +53 -0
  17. package/dist/exports/config.d.ts +2 -0
  18. package/dist/exports/config.js +2 -0
  19. package/dist/exports/log.d.ts +2 -0
  20. package/{src → dist}/exports/log.js +1 -2
  21. package/dist/exports/test-helpers.d.ts +5 -0
  22. package/dist/exports/test-helpers.js +7 -0
  23. package/dist/lifecycle.d.ts +7 -0
  24. package/dist/lifecycle.js +18 -0
  25. package/dist/main.d.ts +22 -0
  26. package/dist/main.js +102 -0
  27. package/dist/modules.d.ts +5 -0
  28. package/dist/modules.js +186 -0
  29. package/dist/util/duplicate-core.d.ts +186 -0
  30. package/dist/util/duplicate-core.js +377 -0
  31. package/dist/util/import-config.d.ts +52 -0
  32. package/dist/util/import-config.js +256 -0
  33. package/dist/util/resolve-entry-point.d.ts +1 -0
  34. package/dist/util/resolve-entry-point.js +14 -0
  35. package/dist/util/resolve-module-name.d.ts +14 -0
  36. package/dist/util/resolve-module-name.js +33 -0
  37. package/package.json +41 -12
  38. package/scripts/postinstall-manifest.js +16 -0
  39. package/scripts/postinstall.js +17 -2
  40. package/.claude/index.md +0 -96
  41. package/.github/workflows/ci.yml +0 -16
  42. package/.github/workflows/publish.yml +0 -51
  43. package/docs/api.md +0 -89
  44. package/docs/cli.md +0 -78
  45. package/docs/configuration.md +0 -72
  46. package/docs/conventions/cron-conventions.md +0 -195
  47. package/docs/conventions/discord-conventions.md +0 -62
  48. package/docs/conventions/framework-modules.md +0 -140
  49. package/docs/conventions/index.md +0 -25
  50. package/docs/conventions/orm-conventions.md +0 -190
  51. package/docs/conventions/project-structure.md +0 -105
  52. package/docs/conventions/rest-conventions.md +0 -96
  53. package/docs/conventions/testing-conventions.md +0 -56
  54. package/docs/developing-modules.md +0 -108
  55. package/docs/index.md +0 -15
  56. package/docs/lifecycle.md +0 -47
  57. package/docs/logging.md +0 -52
  58. package/docs/modules.md +0 -78
  59. package/docs/testing.md +0 -64
  60. package/src/cli/help.js +0 -48
  61. package/src/cli/load-commands.js +0 -56
  62. package/src/cli/new.js +0 -237
  63. package/src/cli/serve.js +0 -38
  64. package/src/cli/test-setup.js +0 -8
  65. package/src/cli/test.js +0 -27
  66. package/src/cli.js +0 -63
  67. package/src/exports/config.js +0 -3
  68. package/src/exports/test-helpers.js +0 -8
  69. package/src/lifecycle.js +0 -17
  70. package/src/main.js +0 -101
  71. package/src/modules.js +0 -112
@@ -1,190 +0,0 @@
1
- # ORM Conventions
2
-
3
- ## Models
4
-
5
- Models define the data structure with attributes and relationships. One model per file in `models/`.
6
-
7
- **Property ordering:** `attr()` → `belongsTo()` / `hasMany()` → computed getters
8
-
9
- ```js
10
- import { Model, attr, belongsTo, hasMany } from '@stonyx/orm';
11
- import { ANIMALS } from '../constants.js';
12
-
13
- export default class AnimalModel extends Model {
14
- type = attr('animal');
15
- age = attr('number');
16
- size = attr('string');
17
-
18
- owner = belongsTo('owner');
19
- traits = hasMany('trait');
20
-
21
- get tag() {
22
- const { owner, size } = this;
23
-
24
- if (!owner) {
25
- return `Unowned ${size} ${ANIMALS[this.type]}`;
26
- }
27
-
28
- return `${owner.id}'s ${size} ${ANIMALS[this.type]}`;
29
- }
30
- }
31
- ```
32
-
33
- ### Property Flattening
34
-
35
- Every property must resolve to a final data type — no passthrough objects. If an API returns a nested object, create a sub-model with `belongsTo` rather than storing the raw object.
36
-
37
- ### Nested Models
38
-
39
- Use nested directories for `belongsTo` children:
40
-
41
- ```
42
- models/
43
- character.js
44
- character/
45
- relationship.js
46
- ```
47
-
48
- ## Serializers
49
-
50
- Serializers map raw external data to the model shape. One serializer per model in `serializers/`.
51
-
52
- The serializer has a single `map` property. It is responsible for mapping only, not fetching.
53
-
54
- ```js
55
- import { Serializer } from '@stonyx/orm';
56
-
57
- const COLOR_TRAIT_MAP = {
58
- 'black': 2,
59
- 'white': 3,
60
- }
61
-
62
- export default class AnimalSerializer extends Serializer {
63
- map = {
64
- age: 'details.age',
65
- size: 'details.c',
66
- color: 'details.x',
67
- owner: 'details.location.owner',
68
-
69
- // Array value: [sourcePath, customHandler]
70
- traits: ['details', ({ x:color }) => {
71
- const traits = [{ id: 1, type: 'habitat', value: 'farm', category: 'physical' }];
72
-
73
- const id = COLOR_TRAIT_MAP[color];
74
- if (id) traits.push({ id, type: 'color', value: color, category: 'appearance' });
75
-
76
- return traits;
77
- }]
78
- }
79
- }
80
- ```
81
-
82
- ### Clients vs Serializers
83
-
84
- - **Clients** fetch, decrypt, and provide raw data from external sources
85
- - **Serializers** map that raw data to the model shape
86
-
87
- Clients handle I/O; serializers handle structure. Never mix the two.
88
-
89
- ## Access Control
90
-
91
- Access classes define which models they govern and implement an `access()` method. One access file per logical access boundary in `access/`.
92
-
93
- **Structure:** `models` property → `access()` method
94
-
95
- ```js
96
- export default class GlobalAccess {
97
- models = ['owner', 'animal', 'trait', 'category', 'phone-number'];
98
-
99
- access(request) {
100
- const { originalUrl: url } = request;
101
-
102
- // Return false to deny
103
- if (url.endsWith('/owners/angela')) return false;
104
-
105
- // Return a filter function for conditional access
106
- if (url.endsWith('/owners')) return record => record.id !== 'angela';
107
- if (url.endsWith('/animals')) return record => record.owner !== 'angela';
108
-
109
- // Return permission array for full access
110
- return ['read', 'create', 'update', 'delete'];
111
- }
112
- }
113
- ```
114
-
115
- The `models` property accepts an array of model names, or `'*'` to match all models.
116
-
117
- `access()` return values:
118
- - `false` — deny access
119
- - `function` — filter function applied to response records
120
- - `string[]` — allowed operations (e.g., `['read', 'create', 'update', 'delete']`)
121
-
122
- ## Transforms
123
-
124
- Transforms are default-exported functions (not classes) that convert values. One transform per model in `transforms/`.
125
-
126
- ```js
127
- import { ANIMALS } from '../constants.js';
128
-
129
- const codeEnumMap = {}
130
-
131
- for (let i = 0; i < ANIMALS.length; i++) codeEnumMap[ANIMALS[i]] = i;
132
-
133
- export default function(value) {
134
- return codeEnumMap[value] || 0;
135
- }
136
- ```
137
-
138
- ## Hooks
139
-
140
- Use `beforeHook` / `afterHook` from `@stonyx/orm/hooks`. Place hook files in `hooks/`.
141
-
142
- ## DB Schema
143
-
144
- The database schema extends `Model` and uses `hasMany` for each collection:
145
-
146
- ```js
147
- import { Model, hasMany } from '@stonyx/orm';
148
-
149
- export default class DBModel extends Model {
150
- owners = hasMany('owner');
151
- animals = hasMany('animal');
152
- traits = hasMany('trait');
153
- categories = hasMany('category');
154
- phoneNumbers = hasMany('phone-number');
155
- }
156
- ```
157
-
158
- Located at `config/db-schema.js`, referenced from `config/environment.js`.
159
-
160
- ## Store
161
-
162
- The store is the in-memory data layer. Use it for internal app logic (not REST API consumers).
163
-
164
- ```js
165
- import Orm, { store, createRecord, updateRecord } from '@stonyx/orm';
166
-
167
- // Read — sync, from memory (requires memory: true on model, which is the default)
168
- const record = store.get('animal', 1);
169
- const allAnimals = store.data.get('animals');
170
-
171
- // Read — async, queries DB if memory: false
172
- const record = await store.find('animal', 1);
173
- const all = await store.findAll('animal');
174
-
175
- // Create — adds to store and returns the record
176
- const animal = createRecord('animal', { type: 'dog', age: 3, owner: 'angela' });
177
-
178
- // Update — patches fields on an existing record
179
- updateRecord(animal, { age: 4 });
180
-
181
- // Delete
182
- store.remove('animal', 1);
183
-
184
- // Persist to disk — required when not using REST-triggered autosave
185
- await Orm.db.save();
186
- ```
187
-
188
- **When to use `Orm.db.save()`**: The `autosave: 'onUpdate'` config only triggers on REST POST/PATCH/DELETE. When modifying data directly via `createRecord` / `updateRecord` in app code (not through REST), call `Orm.db.save()` explicitly to persist.
189
-
190
- **Store vs REST**: Use `store` for internal app logic (session tracking, state management). Use REST request handlers for external API consumers. Both operate on the same in-memory data.
@@ -1,105 +0,0 @@
1
- # Project Structure
2
-
3
- ## Entry Point
4
-
5
- The application entry point is always `app.js` at the project root. This file exports a default class that initializes the application.
6
-
7
- ```js
8
- import log from 'stonyx/log';
9
-
10
- export default class App {
11
- constructor() {
12
- if (App.instance) return App.instance;
13
- App.instance = this;
14
-
15
- this.ready = this.init();
16
- }
17
-
18
- async init() {
19
- log.info('Initializing Application');
20
- // Application setup here
21
- log.info('Application has been initialized');
22
- }
23
- }
24
- ```
25
-
26
- ## File Layout
27
-
28
- Flat file structure at root level — non-directory project files live at the project root.
29
-
30
- ### Standard Directories
31
-
32
- | Directory | Purpose | When to create |
33
- |-----------|---------|----------------|
34
- | `config/` | Configuration files | Always |
35
- | `models/` | ORM model definitions | When using `@stonyx/orm` |
36
- | `serializers/` | Data serializers | When using `@stonyx/orm` |
37
- | `access/` | Access control definitions | When using `@stonyx/orm` |
38
- | `transforms/` | Value transforms | When using `@stonyx/orm` |
39
- | `hooks/` | Lifecycle hooks | When using `@stonyx/orm` |
40
- | `requests/` | REST request handlers | When using `@stonyx/rest-server` |
41
- | `crons/` | Scheduled tasks | When using `@stonyx/cron` |
42
- | `clients/` | External API clients | When fetching external data |
43
- | `test/`| Tests | Always |
44
- | `utils.js` or `utils/` | Project-specific reusable logic | As needed (never duplicate `@stonyx/utils`) |
45
-
46
- ### Nested Model Directories
47
-
48
- Use nested directories under `models/` for `belongsTo` child models:
49
-
50
- ```
51
- models/
52
- character.js
53
- character/
54
- relationship.js
55
- ```
56
-
57
- ## Config Conventions
58
-
59
- ### `config/environment.js`
60
-
61
- Destructure env vars at the top, apply defaults with `??`, export a plain object:
62
-
63
- ```js
64
- const {
65
- CORS_ORIGIN,
66
- DB_FILE,
67
- NODE_ENV,
68
- REST_PORT,
69
- } = process.env;
70
-
71
- const environment = NODE_ENV ?? 'development';
72
-
73
- export default {
74
- orm: {
75
- db: {
76
- file: DB_FILE ?? 'db.json',
77
- schema: './config/db-schema.js'
78
- }
79
- },
80
- restServer: {
81
- origin: CORS_ORIGIN ?? '*',
82
- port: REST_PORT ?? 3000
83
- }
84
- }
85
- ```
86
-
87
- **Do NOT re-declare module defaults.** Only include config values that differ from the module's built-in defaults.
88
-
89
- ### `config/db-schema.js`
90
-
91
- Extends `Model` and uses `hasMany` to define each collection:
92
-
93
- ```js
94
- import { Model, hasMany } from '@stonyx/orm';
95
-
96
- export default class DBModel extends Model {
97
- owners = hasMany('owner');
98
- animals = hasMany('animal');
99
- }
100
- ```
101
-
102
- ## Reference Projects
103
-
104
- - `smart-lock-backend/` — full example with REST, ORM, sockets, crons, hooks
105
- - `nextgoal-backend/` — example with models, transforms, filters, bot commands
@@ -1,96 +0,0 @@
1
- # REST Conventions
2
-
3
- ## Request Classes
4
-
5
- One request class per file in `requests/`. Each class extends `Request` from `@stonyx/rest-server`.
6
-
7
- **Class ordering:** properties → `handlers` object → `auth()` hook → validation/middleware methods
8
-
9
- ### Public Request (no auth)
10
-
11
- ```js
12
- import { Request } from '@stonyx/rest-server';
13
-
14
- export default class PublicRequest extends Request {
15
- testProp = 'stonyx';
16
-
17
- handlers = {
18
- get: {
19
- '/': (_request, _state) => {
20
- return { data: 'foo' };
21
- },
22
-
23
- '/url-params/:x/:y/:z': ({ params }, _state) => {
24
- return params;
25
- },
26
-
27
- // Middleware chaining: [middlewareFn, handlerFn]
28
- '/foo': [this.validationSuccessSample, (_request, state) => {
29
- return { data: state };
30
- }],
31
-
32
- '/fail': [this.validationFailureSample, (_request, _state) => {
33
- return { unreachable: 'response' };
34
- }],
35
- }
36
- }
37
-
38
- validationSuccessSample(_request, state) {
39
- state.newProp = 'bar';
40
- }
41
-
42
- validationFailureSample() {
43
- return 504; // returning a status code rejects the request
44
- }
45
- }
46
- ```
47
-
48
- ### Private Request (with auth)
49
-
50
- ```js
51
- import { Request } from '@stonyx/rest-server';
52
-
53
- export default class PrivateRequest extends Request {
54
- handlers = {
55
- get: {
56
- '/success': (_request, _state) => {
57
- return { data: 'foo' };
58
- },
59
-
60
- '/failure': (_request, _state) => {
61
- return { data: 'foo' };
62
- }
63
- }
64
- }
65
-
66
- auth(request, _state) {
67
- if (request.path === '/failure') return 505;
68
- }
69
- }
70
- ```
71
-
72
- ## Key Patterns
73
-
74
- ### `handlers` Object
75
-
76
- Keyed by HTTP method (`get`, `post`, `put`, `delete`), each containing route-to-handler mappings.
77
-
78
- Handler signature: `(request, state) => responseData`
79
-
80
- ### Middleware Chaining
81
-
82
- Use `[middlewareFn, handlerFn]` arrays to chain middleware before a handler. The middleware function receives `(request, state)` and can:
83
- - Mutate `state` to pass data to the handler
84
- - Return a status code number to reject the request early
85
-
86
- ### `auth()` Hook
87
-
88
- Runs before all handlers in the class. Return an error status code to reject the request. If `auth()` returns nothing (undefined), the request proceeds.
89
-
90
- ### Route Parameters
91
-
92
- Express-style route params (`:param`) are available via `request.params`.
93
-
94
- ### Binding
95
-
96
- Handler functions defined as arrow functions or class methods have access to `this` (the request class instance).
@@ -1,56 +0,0 @@
1
- # Testing Conventions
2
-
3
- ## Directory Structure
4
-
5
- ```
6
- test/
7
- unit/
8
- integration/
9
- acceptance/
10
- config/
11
- environment.js # test config overrides
12
- sample/ # fixtures and mocks (alternative: test/mocks/)
13
- ```
14
-
15
- ## File Naming
16
-
17
- All test files use the `*-test.js` suffix: `animal-test.js`, `public-request-test.js`.
18
-
19
- ## Test Framework
20
-
21
- - **QUnit** — test framework
22
- - **Sinon** — stubs, spies, and mocks
23
-
24
- Run tests with `stonyx test` (alias: `stonyx t`), which:
25
- 1. Sets `NODE_ENV=test`
26
- 2. Loads test setup (bootstrap with test config overrides)
27
- 3. Runs QUnit against `test/**/*-test.js`
28
-
29
- ## Test Config Overrides
30
-
31
- Place test-specific config at `test/config/environment.js`. Stonyx auto-merges these overrides when running in test mode.
32
-
33
- ## Sample / Fixture Files
34
-
35
- Each stonyx module's `test/sample/` directory contains reference implementations. Mirror this structure in your project tests:
36
-
37
- - `test/sample/models/` — model fixtures
38
- - `test/sample/serializers/` — serializer fixtures
39
- - `test/sample/access/` — access control fixtures
40
- - `test/sample/transforms/` — transform fixtures
41
- - `test/sample/requests/` — request handler fixtures
42
-
43
- The file ordering in tests should mirror the sample files from each module's `test/sample/` directory.
44
-
45
- ## Running Tests
46
-
47
- ```bash
48
- # Run all tests
49
- stonyx test
50
-
51
- # Run specific test file
52
- stonyx test test/unit/animal-test.js
53
-
54
- # Run specific glob
55
- stonyx test "test/integration/**/*-test.js"
56
- ```
@@ -1,108 +0,0 @@
1
- # Developing Modules
2
-
3
- Guide for building custom Stonyx modules.
4
-
5
- ## Package Setup
6
-
7
- Your module's `package.json` must include:
8
-
9
- ```json
10
- {
11
- "name": "@stonyx/my-module",
12
- "keywords": ["stonyx-module"],
13
- "main": "src/index.js"
14
- }
15
- ```
16
-
17
- Add `stonyx-async` to keywords if your module requires asynchronous initialization.
18
-
19
- ## Module Class
20
-
21
- Export a default class. Optionally define `init()`, `startup()`, and `shutdown()` methods:
22
-
23
- ```js
24
- export default class MyModule {
25
- // Called during module loading (async modules only)
26
- async init() {
27
- // Connect to services, load resources, etc.
28
- }
29
-
30
- // Called after ALL modules are initialized, before app entry runs
31
- async startup() {
32
- // Register routes, start listeners, etc.
33
- }
34
-
35
- // Called on SIGTERM/SIGINT, in reverse load order
36
- async shutdown() {
37
- // Close connections, flush data, etc.
38
- }
39
- }
40
- ```
41
-
42
- ## Default Configuration
43
-
44
- Async modules must include `config/environment.js` with sensible defaults:
45
-
46
- ```js
47
- export default {
48
- logColor: 'cyan',
49
- logMethod: 'myModule',
50
- logTimestamp: true,
51
- // Module-specific defaults...
52
- };
53
- ```
54
-
55
- User project config is merged on top of these defaults.
56
-
57
- ## Waiting for Other Modules
58
-
59
- If your module depends on another async module being ready:
60
-
61
- ```js
62
- import { waitForModule } from 'stonyx';
63
-
64
- export default class MyModule {
65
- async init() {
66
- await waitForModule('rest-server');
67
- // @stonyx/rest-server is now fully initialized
68
- }
69
- }
70
- ```
71
-
72
- Pass the module name without the `@stonyx/` prefix.
73
-
74
- ## Standalone Development
75
-
76
- When running a module standalone (project path contains `stonyx-`), Stonyx auto-transforms the config structure. Your module's config is wrapped under its camelCase name:
77
-
78
- ```js
79
- // If your module is @stonyx/rest-server and config is { port: 3000 }
80
- // Stonyx transforms it to: { restServer: { port: 3000 } }
81
- ```
82
-
83
- ## Custom CLI Commands
84
-
85
- Modules can register CLI commands by adding a `./commands` export:
86
-
87
- ```json
88
- {
89
- "exports": {
90
- "./commands": "./src/commands.js"
91
- }
92
- }
93
- ```
94
-
95
- ```js
96
- // src/commands.js
97
- export default {
98
- 'my-module:setup': {
99
- description: 'Initialize module resources',
100
- bootstrap: true,
101
- run: async ({ args, cwd }) => {
102
- // Command implementation
103
- }
104
- }
105
- };
106
- ```
107
-
108
- Use namespaced command names (e.g., `my-module:setup`) to avoid conflicts with other modules. See [CLI](cli.md#module-commands) for details.
package/docs/index.md DELETED
@@ -1,15 +0,0 @@
1
- # Stonyx Documentation
2
-
3
- ## Guides
4
-
5
- - [CLI](cli.md) — Commands, usage, and module-contributed commands
6
- - [Configuration](configuration.md) — Environment config, module config, and test overrides
7
- - [Modules](modules.md) — Module discovery, sync vs async, and official modules
8
- - [Lifecycle](lifecycle.md) — Startup/shutdown hooks and signal handling
9
- - [Logging](logging.md) — Color-coded logging via Chronicle
10
- - [Testing](testing.md) — Running tests, config overrides, and integration helpers
11
- - [Developing Modules](developing-modules.md) — Guide for building custom Stonyx modules
12
-
13
- ## Reference
14
-
15
- - [API Reference](api.md) — Public exports and class documentation
package/docs/lifecycle.md DELETED
@@ -1,47 +0,0 @@
1
- # Lifecycle Hooks
2
-
3
- Stonyx modules can define `startup()` and `shutdown()` methods that run at specific points in the application lifecycle.
4
-
5
- ## Startup Hooks
6
-
7
- Called sequentially (in module load order) after all modules have been initialized, right before your application entry point runs.
8
-
9
- ```js
10
- export default class MyModule {
11
- async startup() {
12
- // Called after all modules are init'd, before app.js runs
13
- }
14
- }
15
- ```
16
-
17
- ## Shutdown Hooks
18
-
19
- Called sequentially in **reverse** module load order when the process receives `SIGTERM` or `SIGINT`. Errors in one hook do not prevent other hooks from running.
20
-
21
- ```js
22
- export default class MyModule {
23
- async shutdown() {
24
- // Clean up connections, flush buffers, etc.
25
- }
26
- }
27
- ```
28
-
29
- ## Signal Handling
30
-
31
- The `stonyx serve` command registers signal handlers automatically:
32
-
33
- - **SIGTERM** — triggers shutdown hooks, then `process.exit(0)`
34
- - **SIGINT** — triggers shutdown hooks, then `process.exit(0)`
35
-
36
- Shutdown is idempotent — calling the handler multiple times only runs hooks once.
37
-
38
- ## Using Lifecycle Hooks Directly
39
-
40
- For advanced use cases, the lifecycle functions are available as a public export:
41
-
42
- ```js
43
- import { runStartupHooks, runShutdownHooks } from 'stonyx/lifecycle';
44
-
45
- await runStartupHooks(modules); // Calls startup() on each module in order
46
- await runShutdownHooks(modules); // Calls shutdown() on each module in reverse order
47
- ```
package/docs/logging.md DELETED
@@ -1,52 +0,0 @@
1
- # Logging
2
-
3
- Stonyx provides centralized, color-coded logging via [Chronicle](https://github.com/abofs/chronicle).
4
-
5
- ## Overview
6
-
7
- Every Stonyx instance creates a Chronicle logger with a default `title` log type (green). Modules and user services can register additional log types with custom colors.
8
-
9
- ## Module Logs
10
-
11
- Modules that specify `logColor` in their configuration automatically get a Chronicle log type:
12
-
13
- ```js
14
- // config/environment.js
15
- export default {
16
- restServer: {
17
- logColor: 'yellow',
18
- logMethod: 'api', // Optional — defaults to the config key name
19
- logTimestamp: true, // Optional — adds timestamps to log output
20
- },
21
- };
22
- ```
23
-
24
- This creates a `chronicle.api()` method that outputs in yellow with timestamps.
25
-
26
- ## Custom Logs
27
-
28
- You can define logs for any class or service in your project — not just Stonyx modules:
29
-
30
- ```js
31
- export default {
32
- myWorker: {
33
- logColor: 'cyan',
34
- logMethod: 'worker',
35
- logTimestamp: true,
36
- },
37
- };
38
- ```
39
-
40
- Any top-level config key with a `logColor` property will have a log type created automatically.
41
-
42
- ## Accessing the Logger
43
-
44
- ```js
45
- import log from 'stonyx/log';
46
-
47
- log.title('Application started');
48
- log.api('Request received'); // If restServer config defines logMethod: 'api'
49
- log.worker('Processing job'); // If myWorker config defines logMethod: 'worker'
50
- ```
51
-
52
- The `stonyx/log` export is a live reference to the Chronicle instance. It will throw if accessed before Stonyx is initialized.