@vicin/sigil 3.2.0 → 3.2.1
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/CHANGELOG.md +6 -0
- package/README.md +32 -24
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -7,19 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
`Sigil` gives you the power of **safe cross-bundle class instances checks** and **simple class nominal typing** if needed.
|
|
9
9
|
|
|
10
|
-
> **Key ideas:**
|
|
11
|
-
>
|
|
12
|
-
> - **Reliable Runtime Checks:** Uses `isOfType` instead of `instanceof` for cross-bundle reliability.
|
|
13
|
-
> - **Nominal Typing at Compile Time:** Distinguishes structurally similar types (e.g., UserId vs. PostId).
|
|
14
|
-
|
|
15
10
|
## Features
|
|
16
11
|
|
|
17
|
-
- ✅ **Drop-in `instanceof` replacement** that works across bundles
|
|
18
|
-
- ✅ **Simple nominal typing** with just one line of code for each class
|
|
12
|
+
- ✅ **Drop-in `instanceof` replacement** that works across bundles and monorepos, Also add check for **exact class instance**
|
|
13
|
+
- ✅ **Simple nominal typing** with just one line of code for each class (e.g., `UserId` vs. `PostId`)
|
|
19
14
|
- ✅ **Tiny less than 1.6 KB minified and brotlied** measured using [size-limit](https://www.npmjs.com/package/size-limit)
|
|
20
15
|
- ✅ **Performant as native instanceof** but with guaranteed checks
|
|
21
16
|
- ✅ **Test coverage is 100%** to ensure that runtime remains consistent and predictable
|
|
22
|
-
- ✅ **Safe with strict rules to ensure uniqueness of labels**, if
|
|
17
|
+
- ✅ **Safe with strict rules to ensure uniqueness of labels**, if duplicate label is passed error is thrown immediately
|
|
23
18
|
|
|
24
19
|
---
|
|
25
20
|
|
|
@@ -35,7 +30,7 @@
|
|
|
35
30
|
- [Terminology](#terminology)
|
|
36
31
|
- [Purpose and Origins](#purpose-and-origins)
|
|
37
32
|
- [Implementation Mechanics](#implementation-mechanics)
|
|
38
|
-
- [
|
|
33
|
+
- [Example](#example)
|
|
39
34
|
- [Errors & throws](#errors--throws)
|
|
40
35
|
- [API reference](#api-reference)
|
|
41
36
|
- [Options & configuration](#options--configuration)
|
|
@@ -90,8 +85,6 @@ abstract class User extends Sigil {}
|
|
|
90
85
|
const MyClass = SigilifyAbstract(abstract class {}, '@myorg/mypkg.MyClass');
|
|
91
86
|
```
|
|
92
87
|
|
|
93
|
-
This adds runtime metadata to the constructor and allows you to use runtime helpers, see [API reference](#api-reference).
|
|
94
|
-
|
|
95
88
|
#### Extend `Sigil` classes
|
|
96
89
|
|
|
97
90
|
After opting into the `Sigil` contract, labels are passed to child classes to uniquely identify them, they can be supplied using two patterns:
|
|
@@ -116,9 +109,6 @@ import { Sigil, withSigil } from '@vicin/sigil';
|
|
|
116
109
|
|
|
117
110
|
class _User extends Sigil {}
|
|
118
111
|
const User = withSigil(_User, '@myorg/mypkg.User');
|
|
119
|
-
|
|
120
|
-
const user = new User();
|
|
121
|
-
console.log(User.SigilLabel); // "@myorg/mypkg.User"
|
|
122
112
|
```
|
|
123
113
|
|
|
124
114
|
### Migration
|
|
@@ -161,10 +151,10 @@ Congratulations — you’ve opted into `Sigil` and you can start replacing `ins
|
|
|
161
151
|
|
|
162
152
|
Sigil addresses issues in large monorepos and Domain-Driven Design (DDD):
|
|
163
153
|
|
|
164
|
-
- **Unreliable `instanceof`:** Bundling
|
|
154
|
+
- **Unreliable `instanceof`:** Bundling cause class redefinitions, breaking checks.
|
|
165
155
|
|
|
166
156
|
```ts
|
|
167
|
-
//
|
|
157
|
+
// Can be broken in monorepo
|
|
168
158
|
if (obj instanceof User) { ... }
|
|
169
159
|
|
|
170
160
|
// With Sigil
|
|
@@ -201,7 +191,7 @@ class MyClass extends Sigil {
|
|
|
201
191
|
}
|
|
202
192
|
```
|
|
203
193
|
|
|
204
|
-
You can avoid decorators and use HOF
|
|
194
|
+
You can avoid decorators and use HOF if needed:
|
|
205
195
|
|
|
206
196
|
```ts
|
|
207
197
|
import { Sigil, withSigil, sigil, ExtendSigil } from '@vicin/sigil';
|
|
@@ -216,7 +206,7 @@ type MyClass = InstanceType<typeof MyClass>;
|
|
|
216
206
|
|
|
217
207
|
Note that you can't use `InstanceType` on `private` or `protected` classes, however you can use `GetPrototype<T>` in such cases.
|
|
218
208
|
|
|
219
|
-
###
|
|
209
|
+
### Example
|
|
220
210
|
|
|
221
211
|
```ts
|
|
222
212
|
import { Sigil, WithSigil } from '@vicin/sigil';
|
|
@@ -241,13 +231,31 @@ console.log(User.isOfType(admin)); // true
|
|
|
241
231
|
console.log(User.isOfType(user)); // true
|
|
242
232
|
|
|
243
233
|
// Exact checks
|
|
244
|
-
console.log(Admin.
|
|
245
|
-
console.log(Admin.
|
|
246
|
-
console.log(User.
|
|
247
|
-
console.log(User.
|
|
248
|
-
|
|
234
|
+
console.log(Admin.isExactType(admin)); // true
|
|
235
|
+
console.log(Admin.isExactType(user)); // false
|
|
236
|
+
console.log(User.isExactType(user)); // true
|
|
237
|
+
console.log(User.isExactType(admin)); // false (Admin is child indeed but this checks for user specifically)
|
|
238
|
+
|
|
239
|
+
// Can use checks from instances
|
|
240
|
+
console.log(admin.isOfType(user)); // false
|
|
241
|
+
console.log(user.isOfType(admin)); // true
|
|
242
|
+
console.log(admin.isExactType(user)); // false
|
|
243
|
+
console.log(user.isExactType(admin)); // false
|
|
244
|
+
|
|
245
|
+
// Type checks are nominal
|
|
249
246
|
type test1 = Admin extends User ? true : false; // true
|
|
250
247
|
type test2 = User extends Admin ? true : false; // false
|
|
248
|
+
|
|
249
|
+
// Passed label must be unique (enforced by Sigil) so can be used as stable Id for class
|
|
250
|
+
// Also 'SigilLabelLineage' and 'SigilLabelSet' are useful for logging & debugging
|
|
251
|
+
console.log(Admin.SigilLabel); // '@myorg/Admin'
|
|
252
|
+
console.log(Admin.SigilEffectiveLabel); // '@myorg/Admin'
|
|
253
|
+
console.log(Admin.SigilLabelLineage); // ['Sigil', '@myorg/User', '@myorg/Admin']
|
|
254
|
+
console.log(Admin.SigilLabelSet); // Set(['Sigil', '@myorg/User', '@myorg/Admin'])
|
|
255
|
+
console.log(admin.getSigilLabel()); // '@myorg/Admin'
|
|
256
|
+
console.log(admin.getSigilEffectiveLabel()); // '@myorg/Admin'
|
|
257
|
+
console.log(admin.getSigilLabelLineage()); // ['Sigil', '@myorg/User', '@myorg/Admin']
|
|
258
|
+
console.log(admin.getSigilLabelSet()); // Set(['Sigil', '@myorg/User', '@myorg/Admin'])
|
|
251
259
|
```
|
|
252
260
|
|
|
253
261
|
### Errors & throws
|
|
@@ -382,7 +390,7 @@ updateSigilOptions({ labelValidation: 123 as any }); // Throws: 'updateSigilOpti
|
|
|
382
390
|
|
|
383
391
|
### Instance & static helpers provided by Sigilified constructors
|
|
384
392
|
|
|
385
|
-
When a constructor is
|
|
393
|
+
When a constructor is sigilified it will expose the following **static** getters/methods:
|
|
386
394
|
|
|
387
395
|
- `SigilLabel` — the identity label string.
|
|
388
396
|
- `SigilEffectiveLabel` — the human label string.
|
package/package.json
CHANGED