utilium 1.10.1 → 2.0.0-pre.2

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,40 @@
1
1
  import type { ClassLike } from '../types.js';
2
2
  import type * as primitive from './primitives.js';
3
3
 
4
- declare global {
5
- interface SymbolConstructor {
6
- readonly size: unique symbol;
7
- readonly serialize: unique symbol;
8
- readonly deserialize: unique symbol;
9
- }
10
- }
11
-
12
4
  /**
13
5
  * Polyfill Symbol.metadata
14
6
  * @see https://github.com/microsoft/TypeScript/issues/53461
15
7
  */
16
8
  (Symbol as { metadata: symbol }).metadata ??= Symbol.for('Symbol.metadata');
17
9
 
18
- Object.assign(Symbol, {
19
- size: Symbol('uSize'),
20
- serialize: Symbol('uSerialize'),
21
- deserialize: Symbol('uDeserialize'),
22
- });
23
-
24
- export type TypeLike = Custom | Like | primitive.Valid | undefined | null;
25
-
26
- export type Type = Custom | Static | primitive.Typename;
10
+ export type TypeLike = primitive.Type | Like | primitive.Valid | undefined | null;
27
11
 
28
- /**
29
- * Member initialization data
30
- * This is needed since class decorators are called *after* member decorators
31
- */
32
- export interface MemberInit {
33
- name: string;
34
- type: string | ClassLike;
35
- length?: number | string;
36
- }
12
+ export type Type = Static | primitive.Type;
37
13
 
38
14
  /**
39
15
  * Options for struct initialization
40
16
  */
41
17
  export interface Options {
18
+ packed: boolean;
42
19
  align: number;
43
- bigEndian: boolean;
44
20
  isUnion: boolean;
45
21
  }
46
22
 
47
23
  export interface Member {
48
24
  name: string;
49
25
  type: Type;
50
- staticOffset: number;
51
- length?: number | string;
26
+ offset: number;
27
+
28
+ /** The size of the member, 0 for dynamically sized arrays */
29
+ size: number;
30
+ length?: number;
31
+ countedBy?: string;
52
32
 
53
33
  /** A C-style type/name declaration string, used for diagnostics */
54
34
  decl: string;
35
+
36
+ /** Whether the member is little endian */
37
+ littleEndian: boolean;
55
38
  }
56
39
 
57
40
  export interface Metadata {
@@ -66,9 +49,16 @@ export interface Metadata {
66
49
  isUnion: boolean;
67
50
  }
68
51
 
52
+ export interface Init {
53
+ members: Member[];
54
+ size: number;
55
+ isDynamic: boolean;
56
+ isUnion: boolean;
57
+ }
58
+
69
59
  type _DecoratorMetadata<T extends Metadata = Metadata> = DecoratorMetadata & {
70
60
  struct?: T;
71
- structInit?: MemberInit[];
61
+ structInit?: Init;
72
62
  };
73
63
 
74
64
  export interface DecoratorContext<T extends Metadata = Metadata> {
@@ -79,25 +69,34 @@ export interface DecoratorContext<T extends Metadata = Metadata> {
79
69
  * Initializes the struct metadata for a class
80
70
  * This also handles copying metadata from parent classes
81
71
  */
82
- export function initMetadata(context: DecoratorContext): MemberInit[] {
72
+ export function initMetadata(context: DecoratorContext): Init {
83
73
  context.metadata ??= {};
84
74
 
85
- context.metadata.structInit = [...(context.metadata.structInit ?? [])];
75
+ const existing: Partial<Init> = context.metadata.structInit ?? {};
76
+
77
+ context.metadata.structInit = {
78
+ members: [...(existing.members ?? [])],
79
+ size: existing.size ?? 0,
80
+ isDynamic: existing.isDynamic ?? false,
81
+ isUnion: existing.isUnion ?? false,
82
+ };
86
83
 
87
84
  return context.metadata.structInit;
88
85
  }
89
86
 
90
- export type MemberContext = ClassMemberDecoratorContext & DecoratorContext;
91
-
92
87
  export interface Static<T extends Metadata = Metadata> {
93
- [Symbol.metadata]: { struct: T };
94
- new (): Instance<T>;
95
- prototype: Instance<T>;
88
+ [Symbol.metadata]: Required<_DecoratorMetadata<T>>;
89
+ readonly prototype: Instance<T>;
90
+ new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
91
+ buffer: TArrayBuffer,
92
+ byteOffset?: number,
93
+ length?: number
94
+ ): Instance<T> & ArrayBufferView<TArrayBuffer>;
95
+ new (array?: ArrayLike<number> | ArrayBuffer): Instance<T>;
96
96
  }
97
97
 
98
98
  export interface StaticLike<T extends Metadata = Metadata> extends ClassLike {
99
99
  [Symbol.metadata]?: _DecoratorMetadata<T> | null;
100
- new (): unknown;
101
100
  }
102
101
 
103
102
  export function isValidMetadata<T extends Metadata = Metadata>(
@@ -108,27 +107,11 @@ export function isValidMetadata<T extends Metadata = Metadata>(
108
107
  return arg != null && typeof arg == 'object' && 'struct' in arg;
109
108
  }
110
109
 
111
- /**
112
- * Polyfill context.metadata
113
- * @see https://github.com/microsoft/TypeScript/issues/53461
114
- * @internal @hidden
115
- */
116
- export function _polyfill_metadata(target: object): void {
117
- if (Symbol.metadata in target) return;
118
-
119
- Object.defineProperty(target, Symbol.metadata, {
120
- enumerable: true,
121
- configurable: true,
122
- writable: true,
123
- value: Object.create(null),
124
- });
125
- }
126
-
127
110
  export function isStatic<T extends Metadata = Metadata>(arg: unknown): arg is Static<T> {
128
111
  return typeof arg == 'function' && Symbol.metadata in arg && isValidMetadata(arg[Symbol.metadata]);
129
112
  }
130
113
 
131
- export interface Instance<T extends Metadata = Metadata> {
114
+ export interface Instance<T extends Metadata = Metadata> extends ArrayBufferView, Record<PropertyKey, any> {
132
115
  constructor: Static<T>;
133
116
  }
134
117
 
@@ -162,25 +145,10 @@ export function checkStruct<T extends Metadata = Metadata>(arg: unknown): assert
162
145
  );
163
146
  }
164
147
 
165
- /**
166
- * A "custom" type, which can be used to implement non-builtin size, serialization, and deserialization
167
- */
168
- export interface Custom {
169
- readonly [Symbol.size]: number;
170
- [Symbol.serialize]?(): Uint8Array;
171
- [Symbol.deserialize]?(value: Uint8Array): void;
172
- }
173
-
174
- export function isCustom(arg: unknown): arg is Custom {
175
- return typeof arg == 'object' && arg != null && Symbol.size in arg;
176
- }
177
-
178
148
  export type Like<T extends Metadata = Metadata> = InstanceLike<T> | StaticLike<T>;
179
149
 
180
150
  export type Size<T extends TypeLike> = T extends undefined | null
181
151
  ? 0
182
- : T extends { readonly [Symbol.size]: infer S extends number }
183
- ? S
184
- : T extends primitive.Valid
185
- ? primitive.Size<T>
186
- : number;
152
+ : T extends primitive.Valid
153
+ ? primitive.Size<T>
154
+ : number;
package/src/objects.ts CHANGED
@@ -136,3 +136,10 @@ export function bindFunctions<T extends object, This = any>(fns: T, thisValue: T
136
136
  Object.entries(fns).map(([k, v]) => [k, typeof v == 'function' ? v.bind(thisValue) : v])
137
137
  ) as Bound<T, This>;
138
138
  }
139
+
140
+ /**
141
+ * Makes all properties in T mutable
142
+ */
143
+ export type Mutable<T> = {
144
+ -readonly [P in keyof T]: T[P];
145
+ };