mnemonica 1.0.0 → 1.0.6
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/.ai/ONBOARDING.md +1 -1
- package/.ai/ask/AGENTS.md +15 -9
- package/.ai/async_init.md +2 -2
- package/.ai/rules-skill/contributing.md +1 -1
- package/.ai/rules-skill/define-patterns.md +8 -2
- package/.ai/rules-skill/ecosystem.md +4 -4
- package/.ai/rules-skill/instance-methods.md +48 -15
- package/.ai/rules-skill/type-system.md +12 -2
- package/AGENTS.md +6 -2
- package/CONTRIBUTING.md +61 -9
- package/FOR_HUMANS.md +149 -239
- package/README.md +75 -40
- package/SKILL.md +1 -1
- package/build/api/errors/exceptionConstructor.js +20 -12
- package/build/api/errors/index.js +9 -5
- package/build/api/errors/throwModificationError.js +15 -9
- package/build/api/index.js +35 -2
- package/build/api/types/InstanceCreator.js +5 -2
- package/build/api/types/Mnemosyne.d.ts +6 -6
- package/build/api/types/Mnemosyne.js +43 -120
- package/build/api/types/Props.js +5 -3
- package/build/api/types/TypeProxy.js +13 -9
- package/build/api/types/compileNewModificatorFunctionBody.js +14 -8
- package/build/api/types/index.js +56 -13
- package/build/api/utils/index.js +21 -12
- package/build/constants/index.js +11 -8
- package/build/descriptors/types/index.js +79 -26
- package/build/index.d.ts +4 -4
- package/build/index.js +62 -15
- package/build/types/index.d.ts +52 -31
- package/build/types/index.js +1 -1
- package/build/utils/clone.d.ts +1 -0
- package/build/utils/clone.js +11 -0
- package/build/utils/collectConstructors.js +5 -3
- package/build/utils/exception.d.ts +1 -0
- package/build/utils/exception.js +14 -0
- package/build/utils/extract.d.ts +2 -3
- package/build/utils/extract.js +3 -2
- package/build/utils/fork.d.ts +1 -0
- package/build/utils/fork.js +33 -0
- package/build/utils/index.d.ts +2 -3
- package/build/utils/index.js +21 -7
- package/build/utils/merge.d.ts +2 -1
- package/build/utils/merge.js +10 -6
- package/build/utils/parent.d.ts +1 -1
- package/build/utils/parent.js +3 -2
- package/build/utils/parse.d.ts +2 -12
- package/build/utils/parse.js +1 -1
- package/build/utils/pick.d.ts +4 -3
- package/build/utils/pick.js +4 -5
- package/build/utils/sibling.d.ts +1 -0
- package/build/utils/sibling.js +25 -0
- package/build/utils/toJSON.d.ts +1 -1
- package/build/utils/toJSON.js +3 -2
- package/docs/UTILS.md +184 -0
- package/docs/ai-learning-trajectory.md +1 -1
- package/docs/async-constructors.md +3 -1
- package/docs/empathy-in-ai.md +170 -0
- package/docs/hott-primer.md +47 -0
- package/docs/performance-vs-security.md +395 -0
- package/docs/purpose.md +38 -7
- package/docs/tactica-pattern.md +10 -10
- package/docs/theory-of-operations.md +224 -0
- package/docs/typed-lookup.md +12 -12
- package/docs/typeomatica.md +1 -1
- package/package.json +13 -6
- package/src/api/errors/exceptionConstructor.ts +14 -9
- package/src/api/errors/index.ts +8 -4
- package/src/api/errors/throwModificationError.ts +10 -9
- package/src/api/types/InstanceCreator.ts +5 -8
- package/src/api/types/Mnemosyne.ts +72 -231
- package/src/api/types/Props.ts +4 -2
- package/src/api/types/TypeProxy.ts +7 -11
- package/src/api/types/compileNewModificatorFunctionBody.ts +13 -7
- package/src/api/types/index.ts +15 -8
- package/src/api/utils/index.ts +16 -14
- package/src/constants/index.ts +6 -9
- package/src/descriptors/types/index.ts +44 -24
- package/src/index.ts +28 -21
- package/src/types/index.ts +101 -69
- package/src/utils/clone.ts +11 -0
- package/src/utils/collectConstructors.ts +4 -2
- package/src/utils/exception.ts +16 -0
- package/src/utils/extract.ts +5 -2
- package/src/utils/fork.ts +57 -0
- package/src/utils/index.ts +32 -13
- package/src/utils/merge.ts +18 -6
- package/src/utils/parent.ts +4 -6
- package/src/utils/parse.ts +5 -4
- package/src/utils/pick.ts +10 -2
- package/src/utils/sibling.ts +33 -0
- package/src/utils/toJSON.ts +3 -2
package/FOR_HUMANS.md
CHANGED
|
@@ -106,29 +106,19 @@ The key inversion: `new` is called on the **parent instance** (`alice`), not on
|
|
|
106
106
|
|
|
107
107
|
---
|
|
108
108
|
|
|
109
|
-
## Install
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
npm install mnemonica
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Requires Node.js `>=18 <26`.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
109
|
## Where to go next
|
|
120
110
|
|
|
121
|
-
- **Want a guided tour?** Continue reading — [
|
|
111
|
+
- **Want a guided tour?** Continue reading — [Quick Start](#quick-start), [Core Concepts](#core-concepts).
|
|
122
112
|
- **Looking for a specific function?** Jump to the [API Reference](#api-reference).
|
|
123
|
-
- **Curious about the theory?** Read [`README.md`](./README.md) — the HoTT framing, the Trie observation, the AI-agent angle.
|
|
113
|
+
- **Curious about the theory?** Read [`README.md`](./README.md) — the HoTT framing, the Trie observation, the pipeline pattern, the AI-agent angle.
|
|
124
114
|
- **Want examples you can run?** See the [`examples/`](./examples/) directory and [Examples](#examples) below.
|
|
125
115
|
- **Going deeper on philosophy?** Read [`docs/purpose.md`](./docs/purpose.md).
|
|
116
|
+
- **Background reading:** [Inheritance in JavaScript: Factory of Constructors with Prototype Chain](https://github.com/mythographica/stash/blob/master/inheritance.md) · [Architecture of Prototype Inheritance in JavaScript](https://dev.to/wentout/architecture-of-prototype-inheritance-in-javascript-ce6) · [Dead Simple type checker for JavaScript](https://dev.to/wentout/dead-simple-type-checker-for-javascript-4l40)
|
|
126
117
|
|
|
127
118
|
---
|
|
128
119
|
|
|
129
120
|
## Table of Contents
|
|
130
121
|
|
|
131
|
-
- [Overview](#overview)
|
|
132
122
|
- [Installation](#installation)
|
|
133
123
|
- [Quick Start](#quick-start)
|
|
134
124
|
- [For AI Agents](#for-ai-agents)
|
|
@@ -147,36 +137,12 @@ Requires Node.js `>=18 <26`.
|
|
|
147
137
|
- [Symbols & Constants](#symbols--constants)
|
|
148
138
|
- [Configuration Options](#configuration-options)
|
|
149
139
|
- [Examples](#examples)
|
|
150
|
-
- [Usage with TypeØmatica](#usage-with-
|
|
140
|
+
- [Usage with TypeØmatica](#usage-with-typeømatica)
|
|
151
141
|
- [Roadmap](#roadmap)
|
|
152
142
|
- [Contributing](#contributing)
|
|
153
143
|
- [License](#license)
|
|
154
144
|
---
|
|
155
145
|
|
|
156
|
-
## Overview
|
|
157
|
-
|
|
158
|
-
Mnemonica helps create ordered sequences of data transformations using prototype chain inheritance. It combines Object Instances with Inheritance through the Prototype Chain, enabling you to create new instances inherited from existing ones.
|
|
159
|
-
|
|
160
|
-
> For a deeper explanation of what mnemonica is (and is not), see [docs/purpose.md](docs/purpose.md).
|
|
161
|
-
|
|
162
|
-
> *"O Great Mnemosyne! Please! Save us from Oblivion..."*
|
|
163
|
-
>
|
|
164
|
-
> — from the source, where memory persists
|
|
165
|
-
|
|
166
|
-
**Key Features:**
|
|
167
|
-
- Factory of Constructors with Prototype Chain Inheritance
|
|
168
|
-
- Instance-level inheritance (not just class-level)
|
|
169
|
-
- Async constructor support with chainable awaits
|
|
170
|
-
- Type-safe data flow definition
|
|
171
|
-
- Comprehensive hook system for lifecycle events
|
|
172
|
-
|
|
173
|
-
**Related Reading:**
|
|
174
|
-
- [Inheritance in JavaScript: Factory of Constructors with Prototype Chain](https://github.com/mythographica/stash/blob/master/inheritance.md)
|
|
175
|
-
- [Architecture of Prototype Inheritance in JavaScript](https://dev.to/wentout/architecture-of-prototype-inheritance-in-javascript-ce6)
|
|
176
|
-
- [Dead Simple type checker for JavaScript](https://dev.to/wentout/dead-simple-type-checker-for-javascript-4l40)
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
146
|
## Installation
|
|
181
147
|
|
|
182
148
|
```bash
|
|
@@ -357,17 +323,14 @@ console.log(subInstance.some); // 'arguments' (inherited)
|
|
|
357
323
|
console.log(subInstance.other); // 'data needed' (own)
|
|
358
324
|
```
|
|
359
325
|
|
|
360
|
-
### The
|
|
326
|
+
### The `utils.extract()` Utility
|
|
361
327
|
|
|
362
328
|
Extract all inherited properties into a flat object:
|
|
363
329
|
|
|
364
330
|
```js
|
|
365
|
-
const extracted = subInstance.extract();
|
|
366
|
-
// Result: { data, description, other, some }
|
|
367
|
-
|
|
368
|
-
// Or use the standalone utility
|
|
369
331
|
const { utils: { extract } } = require('mnemonica');
|
|
370
|
-
const
|
|
332
|
+
const extracted = extract(subInstance);
|
|
333
|
+
// Result: { data, description, other, some }
|
|
371
334
|
```
|
|
372
335
|
|
|
373
336
|
---
|
|
@@ -478,54 +441,21 @@ const subInstance = call(someInstance, SomeSubType, 'arg1', 'arg2');
|
|
|
478
441
|
|
|
479
442
|
### Exported Type Definitions
|
|
480
443
|
|
|
481
|
-
The
|
|
444
|
+
The most commonly used types for TypeScript projects:
|
|
482
445
|
|
|
483
446
|
```typescript
|
|
484
447
|
import {
|
|
485
|
-
//
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
//
|
|
491
|
-
MnemonicaInstance, // Instance methods interface (extract, pick, parent, fork, etc.)
|
|
492
|
-
Props, // Internal instance properties (__type__, __args__, __parent__, etc.)
|
|
493
|
-
SiblingAccessor, // Sibling type accessor type
|
|
494
|
-
|
|
495
|
-
// Type definition types
|
|
496
|
-
TypeClass, // Base type constructor returned by define()
|
|
497
|
-
IDefinitorInstance, // Definitor instance with define/lookup methods and subtypes
|
|
498
|
-
DecoratedClass, // Type for @decorate decorated classes
|
|
499
|
-
TypeDef, // Type definition object structure
|
|
500
|
-
|
|
501
|
-
// Configuration types
|
|
502
|
-
constructorOptions, // Type config options (strictChain, blockErrors, etc.)
|
|
503
|
-
hooksTypes, // 'preCreation' | 'postCreation' | 'creationError'
|
|
504
|
-
hook, // Hook callback type
|
|
505
|
-
hooksOpts, // Hook options passed to callbacks
|
|
506
|
-
CollectionDef, // Types collection definition
|
|
507
|
-
|
|
508
|
-
// Utility function types
|
|
509
|
-
ApplyFunction, // apply(entity, Ctor, args) => S
|
|
510
|
-
CallFunction, // call(entity, Ctor, ...args) => S
|
|
511
|
-
BindFunction, // bind(entity, Ctor) => (...args) => S
|
|
512
|
-
|
|
513
|
-
// createTypesCollection types — use only when you need isolation
|
|
514
|
-
CreateTypesCollectionFunction, // (config?: constructorOptions) => TypesCollection
|
|
515
|
-
TypesCollection, // Interface returned by createTypesCollection
|
|
516
|
-
|
|
517
|
-
// Configuration helper types
|
|
518
|
-
HideInstanceMethodsOptions, // constructorOptions & { exposeInstanceMethods: true }
|
|
519
|
-
IsHidingMethods<Config>, // Conditional type for exposeInstanceMethods: false detection
|
|
520
|
-
|
|
521
|
-
// Utility types
|
|
522
|
-
Proto<P, T>, // Merges parent P and child T types
|
|
523
|
-
SN, // String-Name map for nested constructors
|
|
524
|
-
SubtypesMap, // Map<string, TypeClass>
|
|
525
|
-
TypeAbsorber, // Main define() function interface with overloads
|
|
448
|
+
IDEF, // Base constructor function type
|
|
449
|
+
MnemonicaInstance, // Instance methods interface (extract, pick, parent, fork, etc.)
|
|
450
|
+
constructorOptions, // Type config options (strictChain, blockErrors, etc.)
|
|
451
|
+
hooksTypes, // 'preCreation' | 'postCreation' | 'creationError'
|
|
452
|
+
hook, // Hook callback type
|
|
453
|
+
TypeClass, // Base type constructor returned by define()
|
|
526
454
|
} from 'mnemonica';
|
|
527
455
|
```
|
|
528
456
|
|
|
457
|
+
Additional types available: `Constructor`, `Props`, `SiblingAccessor`, `IDefinitorInstance`, `DecoratedClass`, `TypeDef`, `CollectionDef`, `hooksOpts`, `ApplyFunction`, `CallFunction`, `BindFunction`, `CreateTypesCollectionFunction`, `TypesCollection`, `HideInstanceMethodsOptions`, `IsHidingMethods`, `Proto`, `SubtypesMap`, `TypeAbsorber`. See [`src/types/index.ts`](./src/types/index.ts) for full definitions.
|
|
458
|
+
|
|
529
459
|
### Generic Type Patterns
|
|
530
460
|
|
|
531
461
|
Define types with proper generic constraints for full type safety:
|
|
@@ -572,6 +502,19 @@ const AsyncTypeNoReturn = define('AsyncType', async function () {
|
|
|
572
502
|
|
|
573
503
|
## API Reference
|
|
574
504
|
|
|
505
|
+
**Quick reference:**
|
|
506
|
+
|
|
507
|
+
| I want to... | Use |
|
|
508
|
+
|---|---|
|
|
509
|
+
| Define a type | `define('Name', ctor)` |
|
|
510
|
+
| Create from instance | `new instance.SubType(args)` |
|
|
511
|
+
| Look up a type | `lookup('Name')` or `lookupTyped('Name')` |
|
|
512
|
+
| Read construction history | `getProps(instance)` |
|
|
513
|
+
| Get parent instance | `utils.parent(instance)` or `utils.parent(instance, 'TypeName')` |
|
|
514
|
+
| Flatten to plain object | `utils.extract(instance)` |
|
|
515
|
+
| Add lifecycle hooks | `type.registerHook('postCreation', cb)` |
|
|
516
|
+
| Use classes | `@decorate()` decorator |
|
|
517
|
+
|
|
575
518
|
### Core Functions
|
|
576
519
|
|
|
577
520
|
#### `define(typeName, constructHandler, config?)`
|
|
@@ -623,7 +566,7 @@ To enable type safety, generate types with tactica:
|
|
|
623
566
|
npx tactica
|
|
624
567
|
```
|
|
625
568
|
|
|
626
|
-
Then include the generated types in your project. See [
|
|
569
|
+
Then include the generated types in your project. See [`docs/typed-lookup.md`](./docs/typed-lookup.md) for details.
|
|
627
570
|
|
|
628
571
|
#### `apply(entity, Constructor, args?)`
|
|
629
572
|
|
|
@@ -657,24 +600,16 @@ const subInstance = createSub('arg1', 'arg2');
|
|
|
657
600
|
|
|
658
601
|
TypeScript decorator for class-based definitions.
|
|
659
602
|
|
|
660
|
-
**Usage Patterns:**
|
|
661
|
-
|
|
662
603
|
```typescript
|
|
663
604
|
import { decorate } from 'mnemonica';
|
|
664
605
|
|
|
665
|
-
//
|
|
606
|
+
// Basic decoration
|
|
666
607
|
@decorate()
|
|
667
608
|
class MyClass {
|
|
668
609
|
field: number = 123;
|
|
669
610
|
}
|
|
670
611
|
|
|
671
|
-
//
|
|
672
|
-
@decorate({ strictChain: false, blockErrors: true })
|
|
673
|
-
class ConfiguredClass {
|
|
674
|
-
field: number = 123;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
// 3. Nested decoration (define as subtype)
|
|
612
|
+
// Nested decoration (define as subtype)
|
|
678
613
|
@decorate()
|
|
679
614
|
class ParentClass {
|
|
680
615
|
parentField: string = 'parent';
|
|
@@ -688,30 +623,23 @@ class ChildClass {
|
|
|
688
623
|
// Create parent instance, then child from it
|
|
689
624
|
const parent = new ParentClass();
|
|
690
625
|
const child = new parent.ChildClass();
|
|
626
|
+
```
|
|
691
627
|
|
|
692
|
-
|
|
693
|
-
@decorate(ParentClass, { strictChain: false })
|
|
694
|
-
class ConfiguredChildClass {
|
|
695
|
-
field: number = 123;
|
|
696
|
-
}
|
|
628
|
+
**With configuration:**
|
|
697
629
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
class BaseDecorator {
|
|
703
|
-
baseField: number = 100;
|
|
630
|
+
```typescript
|
|
631
|
+
@decorate({ strictChain: false, blockErrors: true })
|
|
632
|
+
class ConfiguredClass {
|
|
633
|
+
field: number = 123;
|
|
704
634
|
}
|
|
705
635
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
class ExtendedClass {
|
|
710
|
-
extField: number = 200;
|
|
636
|
+
@decorate(ParentClass, { strictChain: false })
|
|
637
|
+
class ConfiguredChildClass {
|
|
638
|
+
field: number = 123;
|
|
711
639
|
}
|
|
712
640
|
```
|
|
713
641
|
|
|
714
|
-
**Note:**
|
|
642
|
+
**Note:** After a class is decorated with `@decorate()`, it can be used as a decorator for nested types (advanced pattern; may require `@ts-ignore` due to TypeScript limitations with callable class types).
|
|
715
643
|
|
|
716
644
|
#### `registerHook(Constructor, hookType, callback)`
|
|
717
645
|
|
|
@@ -734,7 +662,7 @@ For advanced TypeScript usage, the following types are exported from `mnemonica`
|
|
|
734
662
|
| Type | Description | Usage |
|
|
735
663
|
|------|-------------|-------|
|
|
736
664
|
| `IDEF<T>` | Base constructor function type | `define('Name', fn: IDEF<MyType>)` |
|
|
737
|
-
| `MnemonicaInstance` |
|
|
665
|
+
| `MnemonicaInstance` | Optional helper interface | Can be used when attaching the legacy instance methods to your own prototype |
|
|
738
666
|
| `TypeClass` | Base type constructor | `const MyType: TypeClass = define(...)` |
|
|
739
667
|
| `DecoratedClass<T>` | Decorated class type | `@decorate() class MyClass {}` |
|
|
740
668
|
| `IDefinitorInstance<N, S>` | Constructor with subtypes | Returned by `define()` with `.define()` method |
|
|
@@ -793,12 +721,6 @@ const MyType = myCollection.define('MyType', function () {});
|
|
|
793
721
|
const FoundType = myCollection.lookup('MyType');
|
|
794
722
|
```
|
|
795
723
|
|
|
796
|
-
```js
|
|
797
|
-
const { createTypesCollection } = require('mnemonica');
|
|
798
|
-
const myCollection = createTypesCollection();
|
|
799
|
-
const MyType = myCollection.define('MyType', function () {});
|
|
800
|
-
```
|
|
801
|
-
|
|
802
724
|
**`TypesCollection` Interface:**
|
|
803
725
|
|
|
804
726
|
`createTypesCollection()` returns a `TypesCollection` object with the following interface:
|
|
@@ -836,8 +758,7 @@ const { createTypesCollection } = require('mnemonica');
|
|
|
836
758
|
// Create isolated collection with custom config
|
|
837
759
|
const myCollection = createTypesCollection({
|
|
838
760
|
strictChain: false,
|
|
839
|
-
blockErrors: false
|
|
840
|
-
exposeInstanceMethods: false // Hide instance methods for cleaner API
|
|
761
|
+
blockErrors: false
|
|
841
762
|
});
|
|
842
763
|
|
|
843
764
|
// Define types in isolation
|
|
@@ -872,80 +793,106 @@ setProps(instance, { __timestamp__: Date.now() });
|
|
|
872
793
|
|
|
873
794
|
### Instance Methods
|
|
874
795
|
|
|
875
|
-
|
|
796
|
+
Starting from v1.0.6 these convenience methods are **no longer auto-injected** on instances. Use the standalone utilities from `utils`:
|
|
797
|
+
|
|
798
|
+
```js
|
|
799
|
+
const { utils } = require('mnemonica');
|
|
876
800
|
|
|
877
|
-
|
|
801
|
+
utils.extract(instance);
|
|
802
|
+
utils.pick(instance, 'key');
|
|
803
|
+
utils.parent(instance, 'ParentType');
|
|
804
|
+
utils.fork(instance)(newArgs);
|
|
805
|
+
utils.exception(instance, error);
|
|
806
|
+
utils.sibling(instance);
|
|
807
|
+
utils.clone(instance);
|
|
808
|
+
```
|
|
878
809
|
|
|
879
|
-
|
|
810
|
+
To restore the old instance-method style for a specific root constructor, attach the methods to its prototype **before** passing it to `define()`. See `test/instance-methods-helper.js` for a complete reference pattern.
|
|
880
811
|
|
|
881
|
-
|
|
812
|
+
#### `utils.extract(instance)`
|
|
882
813
|
|
|
883
|
-
|
|
884
|
-
|
|
814
|
+
Extracts all enumerable user properties into a single flat object. TypeScript
|
|
815
|
+
returns `Extracted<T>` — legacy instance-method names are filtered out and
|
|
816
|
+
optionality is preserved from the source type.
|
|
817
|
+
|
|
818
|
+
```ts
|
|
819
|
+
const extracted = utils.extract(instance);
|
|
820
|
+
// hover: { name: string; email: string; age: number; }
|
|
885
821
|
```
|
|
886
822
|
|
|
887
|
-
####
|
|
823
|
+
#### `utils.pick(instance, ...keys)` / `utils.pick(instance, [keys])`
|
|
888
824
|
|
|
889
|
-
Picks specific properties from the instance and its inheritance chain.
|
|
825
|
+
Picks specific properties from the instance and its inheritance chain. Literal
|
|
826
|
+
keys produce a typed subset; dynamic or unknown keys fall back to
|
|
827
|
+
`Record<string, unknown>`.
|
|
890
828
|
|
|
891
|
-
```
|
|
892
|
-
const picked =
|
|
893
|
-
//
|
|
894
|
-
|
|
829
|
+
```ts
|
|
830
|
+
const picked = utils.pick(instance, 'email', 'password');
|
|
831
|
+
// hover: { email: string; password: string; }
|
|
832
|
+
|
|
833
|
+
const pickedArray = utils.pick(instance, ['email', 'password']);
|
|
895
834
|
```
|
|
896
835
|
|
|
897
|
-
####
|
|
836
|
+
#### `utils.parent(instance, constructorName?)`
|
|
898
837
|
|
|
899
838
|
Gets the parent instance. If `constructorName` is provided, walks up the chain.
|
|
839
|
+
The structural return type is `object | undefined`; a specific nominal parent
|
|
840
|
+
type requires a `TypeRegistry` augmentation (see [`docs/typed-lookup.md`](./docs/typed-lookup.md)).
|
|
900
841
|
|
|
901
|
-
```
|
|
902
|
-
const immediateParent =
|
|
903
|
-
const specificParent =
|
|
842
|
+
```ts
|
|
843
|
+
const immediateParent = utils.parent(instance);
|
|
844
|
+
const specificParent = utils.parent(instance, 'UserType'); // object | undefined
|
|
904
845
|
```
|
|
905
846
|
|
|
906
|
-
####
|
|
847
|
+
#### `utils.clone(instance)`
|
|
907
848
|
|
|
908
|
-
|
|
849
|
+
Returns a cloned instance (same parent, same args). The return type is the
|
|
850
|
+
instance type.
|
|
909
851
|
|
|
910
|
-
```
|
|
911
|
-
const cloned =
|
|
912
|
-
// Note: For async constructors, use: await
|
|
852
|
+
```ts
|
|
853
|
+
const cloned = utils.clone(instance);
|
|
854
|
+
// Note: For async constructors, use: await utils.clone(instance)
|
|
913
855
|
```
|
|
914
856
|
|
|
915
|
-
####
|
|
857
|
+
#### `utils.fork(instance)`
|
|
916
858
|
|
|
917
|
-
|
|
859
|
+
Returns a fork constructor for the instance. Call it with optional new
|
|
860
|
+
arguments to create a forked instance from the same parent.
|
|
918
861
|
|
|
919
|
-
```
|
|
920
|
-
const
|
|
921
|
-
const
|
|
922
|
-
|
|
862
|
+
```ts
|
|
863
|
+
const forkFn = utils.fork(instance);
|
|
864
|
+
const forked = forkFn(); // same args
|
|
865
|
+
const forkedWithNewArgs = forkFn('new', 'args');
|
|
866
|
+
// Note: For async constructors, use: await forkFn(...)
|
|
923
867
|
```
|
|
924
868
|
|
|
925
|
-
####
|
|
869
|
+
#### `utils.fork(instance).call(thisArg, ...args)` / `.apply(thisArg, args)`
|
|
926
870
|
|
|
927
871
|
Forks with a different `this` context (useful for Directed Acyclic Graphs).
|
|
928
872
|
|
|
929
|
-
```
|
|
930
|
-
const
|
|
873
|
+
```ts
|
|
874
|
+
const forkFn = utils.fork(instanceA);
|
|
875
|
+
const dagInstance = forkFn.call(instanceB, 'args');
|
|
931
876
|
```
|
|
932
877
|
|
|
933
|
-
####
|
|
878
|
+
#### `utils.exception(instance, error, ...args)`
|
|
934
879
|
|
|
935
|
-
Creates an exception instance from the
|
|
880
|
+
Creates an exception instance from the given instance.
|
|
936
881
|
|
|
937
|
-
```
|
|
938
|
-
const error =
|
|
882
|
+
```ts
|
|
883
|
+
const error = utils.exception(someInstance, new Error('Something went wrong'));
|
|
939
884
|
throw error;
|
|
940
885
|
```
|
|
941
886
|
|
|
942
|
-
####
|
|
887
|
+
#### `utils.sibling(instance)`
|
|
943
888
|
|
|
944
|
-
Access sibling types from the same collection.
|
|
889
|
+
Access sibling types from the same collection. Returns a callable/proxy object
|
|
890
|
+
that resolves to `TypeClass | undefined`.
|
|
945
891
|
|
|
946
|
-
```
|
|
947
|
-
const
|
|
948
|
-
const
|
|
892
|
+
```ts
|
|
893
|
+
const siblingAccessor = utils.sibling(instance);
|
|
894
|
+
const siblingType = siblingAccessor('OtherType');
|
|
895
|
+
const sibling = siblingAccessor.OtherType;
|
|
949
896
|
```
|
|
950
897
|
|
|
951
898
|
---
|
|
@@ -964,7 +911,7 @@ All instances have non-enumerable internal properties:
|
|
|
964
911
|
| `.__stack__` | `string` | Stack trace (if `submitStack: true` in config) |
|
|
965
912
|
| `.__creator__` | `InstanceCreatorContext` | Instance creator reference |
|
|
966
913
|
| `.__timestamp__` | `number` | Creation timestamp (ms since epoch) |
|
|
967
|
-
| `.__self__` | `object` | Self reference to the instance
|
|
914
|
+
| `.__self__` | `object` | Self reference to the instance |
|
|
968
915
|
|
|
969
916
|
---
|
|
970
917
|
|
|
@@ -972,54 +919,28 @@ All instances have non-enumerable internal properties:
|
|
|
972
919
|
|
|
973
920
|
Access via `utils` export:
|
|
974
921
|
|
|
975
|
-
```
|
|
922
|
+
```ts
|
|
976
923
|
const { utils } = require('mnemonica');
|
|
977
924
|
```
|
|
978
925
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
#### `utils.pick(instance, ...keys)`
|
|
983
|
-
Standalone pick function.
|
|
984
|
-
|
|
985
|
-
#### `utils.parent(instance, constructorName?)`
|
|
986
|
-
Standalone parent function.
|
|
987
|
-
|
|
988
|
-
#### `utils.parse(instance)`
|
|
989
|
-
Parses an instance structure, returning:
|
|
990
|
-
- `name`: constructor name
|
|
991
|
-
- `props`: extracted properties
|
|
992
|
-
- `self`: the instance itself
|
|
993
|
-
- `proto`: prototype object
|
|
994
|
-
- `joint`: prototype properties
|
|
995
|
-
- `parent`: parent prototype
|
|
996
|
-
|
|
997
|
-
```js
|
|
998
|
-
const { utils: { parse } } = require('mnemonica');
|
|
999
|
-
const parsed = parse(instance);
|
|
1000
|
-
```
|
|
1001
|
-
|
|
1002
|
-
#### `utils.merge(A, B, ...args)`
|
|
1003
|
-
Merges two instances using fork semantics.
|
|
1004
|
-
|
|
1005
|
-
```js
|
|
1006
|
-
const merged = utils.merge(instanceA, instanceB, 'args');
|
|
1007
|
-
// Note: For async constructors, use: await utils.merge(...)
|
|
1008
|
-
```
|
|
1009
|
-
|
|
1010
|
-
#### `utils.toJSON(instance)`
|
|
1011
|
-
Serializes an instance to JSON.
|
|
926
|
+
All utilities infer their type parameter from the instance argument; no
|
|
927
|
+
explicit `<T>` cast is required for ordinary use.
|
|
1012
928
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
929
|
+
| Utility | Inferred return type |
|
|
930
|
+
|---|---|
|
|
931
|
+
| `utils.extract(instance)` | `Extracted<T>` — plain user-field object |
|
|
932
|
+
| `utils.pick(instance, 'a', 'b')` | `{ a: T['a'], b: T['b'] }` |
|
|
933
|
+
| `utils.clone(instance)` | `T` |
|
|
934
|
+
| `utils.fork(instance)` | `(this: object, ...args: unknown[]) => T` |
|
|
935
|
+
| `utils.parent(instance, path?)` | `object \| undefined` |
|
|
936
|
+
| `utils.sibling(instance)` | `SiblingAccessor` |
|
|
937
|
+
| `utils.merge(A, B, ...args)` | `InstanceResult<Merge<B, A>, constructorOptions>` |
|
|
938
|
+
| `utils.parse(instance)` | `Parsed<T>` |
|
|
939
|
+
| `utils.toJSON(instance)` | `string` |
|
|
940
|
+
| `utils.collectConstructors(instance, flat?)` | `(CallableFunction \| string)[]` |
|
|
941
|
+
|
|
942
|
+
For the full type-level explanation, helper types, and examples, see
|
|
943
|
+
[`docs/UTILS.md`](./docs/UTILS.md).
|
|
1023
944
|
|
|
1024
945
|
---
|
|
1025
946
|
|
|
@@ -1113,10 +1034,11 @@ errors.WRONG_STACK_CLEANER
|
|
|
1113
1034
|
|
|
1114
1035
|
#### Exception Instances
|
|
1115
1036
|
|
|
1116
|
-
When creating exceptions using `
|
|
1037
|
+
When creating exceptions using `utils.exception()`:
|
|
1117
1038
|
|
|
1118
1039
|
```js
|
|
1119
|
-
const
|
|
1040
|
+
const { utils } = require('mnemonica');
|
|
1041
|
+
const error = utils.exception(instance, new Error('Original error'));
|
|
1120
1042
|
|
|
1121
1043
|
// Properties:
|
|
1122
1044
|
error.originalError // The original error
|
|
@@ -1163,8 +1085,7 @@ define('SomeType', function () {}, {
|
|
|
1163
1085
|
submitStack: false, // Collect stack trace as __stack__ property
|
|
1164
1086
|
awaitReturn: true, // Ensure await new Constructor() returns value
|
|
1165
1087
|
ModificationConstructor: fn, // Custom modification constructor
|
|
1166
|
-
asClass: false
|
|
1167
|
-
exposeInstanceMethods: true // Expose instance methods (default: true for backward compatibility)
|
|
1088
|
+
asClass: false // Force class mode (auto-detected by default)
|
|
1168
1089
|
});
|
|
1169
1090
|
```
|
|
1170
1091
|
|
|
@@ -1177,39 +1098,27 @@ define('SomeType', function () {}, {
|
|
|
1177
1098
|
| `submitStack` | `boolean` | `false` | If `true`, collects stack trace and stores as `__stack__` property on instances. |
|
|
1178
1099
|
| `awaitReturn` | `boolean` | `true` | For async constructors, ensures `await new Constructor()` returns the instance. |
|
|
1179
1100
|
| `asClass` | `boolean` | `auto` | Force class mode detection. Usually auto-detected from constructor syntax. |
|
|
1180
|
-
| `exposeInstanceMethods` | `boolean` | `true` | Expose instance methods on the instance. Set to `false` to hide from TypeScript types. See details below. |
|
|
1181
1101
|
| `ModificationConstructor` | `Function` | - | Custom constructor function for internal instance modification. |
|
|
1182
1102
|
|
|
1183
|
-
###
|
|
1184
|
-
|
|
1185
|
-
Controls whether instance methods (`extract()`, `pick()`, `parent()`, `clone`, `fork()`, `exception()`, `sibling()`) are exposed on the instance type.
|
|
1103
|
+
### Instance Method Opt-In
|
|
1186
1104
|
|
|
1187
|
-
|
|
1188
|
-
|-------|----------|
|
|
1189
|
-
| `true` (default) | All instance methods are available directly on instances |
|
|
1190
|
-
| `false` | Methods are hidden from TypeScript types but still accessible via prototype chain |
|
|
1191
|
-
|
|
1192
|
-
**Use Case:** Set to `false` when you want a cleaner public API and don't want internal mnemonica methods cluttering autocomplete/IntelliSense.
|
|
1105
|
+
Starting from v1.0.6 instance methods are **not** exposed on instances by default. Use the standalone `utils` export or attach the methods to your constructor's prototype before calling `define()`:
|
|
1193
1106
|
|
|
1194
1107
|
```typescript
|
|
1195
|
-
import { define,
|
|
1196
|
-
|
|
1197
|
-
// With exposeInstanceMethods: false
|
|
1198
|
-
const CleanType = define('CleanType', function (data) {
|
|
1199
|
-
Object.assign(this, data);
|
|
1200
|
-
}, { exposeInstanceMethods: false });
|
|
1108
|
+
import { define, utils } from 'mnemonica';
|
|
1201
1109
|
|
|
1202
|
-
|
|
1110
|
+
// Preferred: standalone utilities
|
|
1111
|
+
const instance = new MyType({ value: 42 });
|
|
1112
|
+
utils.extract(instance);
|
|
1203
1113
|
|
|
1204
|
-
//
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
utils.extract(instance); // Works!
|
|
1114
|
+
// Legacy opt-in: attach methods to the constructor prototype before define()
|
|
1115
|
+
function MyType(data) {
|
|
1116
|
+
Object.assign(this, data);
|
|
1117
|
+
}
|
|
1118
|
+
Object.defineProperty(MyType.prototype, 'extract', {
|
|
1119
|
+
get() { return () => utils.extract(this); }
|
|
1120
|
+
});
|
|
1121
|
+
const MyTypeWithMethods = define('MyType', MyType);
|
|
1213
1122
|
```
|
|
1214
1123
|
|
|
1215
1124
|
### Override Default Config for Collection
|
|
@@ -1333,7 +1242,8 @@ const usingReactAsProto = ReactDOOMed.call(ReactDOM);
|
|
|
1333
1242
|
|
|
1334
1243
|
```js
|
|
1335
1244
|
// Fork from different parent
|
|
1336
|
-
const
|
|
1245
|
+
const { utils: { fork } } = require('mnemonica');
|
|
1246
|
+
const dagInstance = fork(instanceA).call(instanceB, 'args');
|
|
1337
1247
|
|
|
1338
1248
|
// Or use merge utility
|
|
1339
1249
|
const { utils: { merge } } = require('mnemonica');
|
|
@@ -1363,7 +1273,7 @@ const node = new GraphNode2D({ x: 10, y: 20 });
|
|
|
1363
1273
|
```
|
|
1364
1274
|
|
|
1365
1275
|
This requires a `NestedTypeRegistry` interface augmentation alongside
|
|
1366
|
-
`TypeRegistry` and is generated by [tactica](https://www.npmjs.com/package/
|
|
1276
|
+
`TypeRegistry` and is generated by [`@mnemonica/tactica`](https://www.npmjs.com/package/@mnemonica/tactica).
|
|
1367
1277
|
|
|
1368
1278
|
---
|
|
1369
1279
|
|