@genrojs/bag 0.10.2 → 0.10.3

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/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@genrojs/bag",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "JavaScript port of genro-bag - hierarchical data container",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
+ "types": "./src/index.d.ts",
7
8
  "exports": {
8
- ".": "./src/index.js",
9
+ ".": {
10
+ "types": "./src/index.d.ts",
11
+ "default": "./src/index.js"
12
+ },
9
13
  "./devtools": "./src/devtools/index.js",
10
14
  "./devtools/html-repr.css": "./src/devtools/html-repr.css"
11
15
  },
package/src/index.d.ts ADDED
@@ -0,0 +1,301 @@
1
+ // Copyright 2025 Softwell S.r.l. - SPDX-License-Identifier: Apache-2.0
2
+
3
+ /** Retry policy applied by a resolver when `load()` fails. */
4
+ export interface RetryPolicy {
5
+ maxAttempts: number;
6
+ /** Initial delay in seconds. */
7
+ delay: number;
8
+ backoff: number;
9
+ jitter: boolean;
10
+ /** Error names that trigger a retry. */
11
+ on: string[];
12
+ }
13
+
14
+ /** Predefined retry policies, referenced by name in `retryPolicy`. */
15
+ export const RETRY_POLICIES: {
16
+ network: RetryPolicy;
17
+ aggressive: RetryPolicy;
18
+ gentle: RetryPolicy;
19
+ };
20
+
21
+ /** Options shared by every resolver. */
22
+ export interface BagResolverOptions {
23
+ /** Cache duration in ms. 0 disables the cache, a negative value never expires. */
24
+ cacheTime?: number;
25
+ /** If true, the resolved value is not stored in the node. */
26
+ readOnly?: boolean;
27
+ /** If true, the result is converted to a Bag. */
28
+ asBag?: boolean | null;
29
+ retryPolicy?: RetryPolicy | keyof typeof RETRY_POLICIES | null;
30
+ [key: string]: any;
31
+ }
32
+
33
+ /** Position of a node in a Bag: '>', '<', '#n', '<label', '>label' or an index. */
34
+ export type NodePosition = string | number | null;
35
+
36
+ /** Callback of `Bag.forEach`: receives the node, the context and the sibling index. */
37
+ export type ForEachCallback = (node: BagNode, kwargs: Record<string, any>, index: number) => any;
38
+
39
+ /** Callbacks accepted by `Bag.subscribe`. */
40
+ export interface BagSubscriptionCallbacks {
41
+ update?: ((...args: any[]) => void) | null;
42
+ insert?: ((...args: any[]) => void) | null;
43
+ delete?: ((...args: any[]) => void) | null;
44
+ any?: ((...args: any[]) => void) | null;
45
+ }
46
+
47
+ /** Options of `Bag.toXml`. */
48
+ export interface ToXmlOptions {
49
+ pretty?: boolean;
50
+ encoding?: string;
51
+ docHeader?: boolean | string | null;
52
+ selfClosedTags?: string[] | null;
53
+ }
54
+
55
+ /** Options of `Bag.fromXml`. */
56
+ export interface FromXmlOptions {
57
+ tagAttribute?: string | null;
58
+ }
59
+
60
+ /** Options of `Bag.fromUrl`. */
61
+ export interface FromUrlOptions {
62
+ /** Timeout in seconds. */
63
+ timeout?: number;
64
+ [key: string]: any;
65
+ }
66
+
67
+ /** Options of `Bag.forEach`. */
68
+ export interface ForEachOptions {
69
+ static?: boolean;
70
+ deep?: boolean;
71
+ kwargs?: Record<string, any>;
72
+ }
73
+
74
+ /** Error raised for Bag-specific failures. */
75
+ export class BagException extends Error {
76
+ constructor(message: string);
77
+ }
78
+
79
+ /** Error raised when a resolver cannot be serialized or executed locally. */
80
+ export class BagSerializationError extends Error {
81
+ constructor(message: string);
82
+ }
83
+
84
+ /** Ordered container of BagNodes, addressed by label, index or dotted path. */
85
+ export class Bag implements Iterable<BagNode> {
86
+ /** Wire suffix of the base class in the TYTX registry. */
87
+ static tytxSuffix: string;
88
+ constructor(source?: Record<string, any> | Bag | null);
89
+
90
+ parent: Bag | null;
91
+ parentNode: BagNode | null;
92
+ readonly backref: boolean;
93
+ readonly nodeClass: typeof BagNode;
94
+ readonly fullpath: string | null;
95
+ readonly length: number;
96
+ readonly root: Bag;
97
+ readonly attributes: Record<string, any>;
98
+ rootAttributes: Record<string, any> | null;
99
+ readonly nodes: BagNode[];
100
+
101
+ createChildBag(): Bag;
102
+ relativePath(node: BagNode): string | null;
103
+
104
+ get(label: string | number, defaultValue?: any, isStatic?: boolean, kwargs?: Record<string, any>): any;
105
+ getItem(path: string, defaultValue?: any, isStatic?: boolean, kwargs?: Record<string, any>): any;
106
+ setItem(path: string, value: any, attr?: Record<string, any> | null, nodePosition?: NodePosition,
107
+ updattr?: boolean, removeNullAttributes?: boolean, reason?: string | null, fired?: boolean,
108
+ doTrigger?: boolean, resolver?: BagResolver | false | null, nodeTag?: string | null): BagNode;
109
+ pop(path: string, defaultValue?: any, reason?: string | null): any;
110
+ delItem(path: string, defaultValue?: any, reason?: string | null): any;
111
+ popNode(path: string, reason?: string | null): BagNode | null;
112
+ clear(): void;
113
+ getNode(path: string | number, isStatic?: boolean, autocreate?: boolean, defaultValue?: any): BagNode | null;
114
+ node(key: string | number): BagNode | null;
115
+ setdefault(path: string, defaultVal?: any): any;
116
+ has(what: string): boolean;
117
+
118
+ setBackref(node?: BagNode | null, parent?: Bag | null): void;
119
+ delParentRef(): void;
120
+ clearBackref(): void;
121
+ subscribe(subscriberId: string, callbacks?: BagSubscriptionCallbacks): void;
122
+ unsubscribe(subscriberId: string, options?: { update?: boolean; insert?: boolean; delete?: boolean; any?: boolean }): void;
123
+
124
+ keys(): string[];
125
+ values(): any[];
126
+ items(): Array<[string, any]>;
127
+ [Symbol.iterator](): Iterator<BagNode>;
128
+
129
+ setAttr(path?: string | null, attr?: Record<string, any> | null, removeNullAttributes?: boolean): void;
130
+ getAttr(path?: string | null, attr?: string | null, defaultVal?: any): any;
131
+ delAttr(path?: string | null, ...attrs: string[]): void;
132
+ getInheritedAttributes(): Record<string, any>;
133
+
134
+ getNodes(condition?: ((node: BagNode) => boolean) | null): BagNode[];
135
+ getNodeByValue(key: string, value: any): BagNode | null;
136
+ getNodeByAttr(attr: string, value: any, caseInsensitive?: boolean, deep_first?: boolean): BagNode | null;
137
+ isEmpty(zeroIsNone?: boolean, blankIsNone?: boolean): boolean;
138
+ query(what?: string | ((node: BagNode) => any) | null, condition?: ((node: BagNode) => boolean) | boolean | null,
139
+ iter?: boolean, deep?: boolean, leaf?: boolean, branch?: boolean, limit?: number | null,
140
+ isStatic?: boolean): any[] | Generator<any>;
141
+ getLeaves(): Array<[string, any]>;
142
+ digest(what?: string | null, condition?: ((node: BagNode) => boolean) | null, asColumns?: boolean): any[];
143
+ columns(cols: string | string[], attrMode?: boolean): any[][];
144
+ sum(what?: string, strict?: boolean, condition?: ((node: BagNode) => boolean) | null): number | null;
145
+ sort(key?: string | ((node: BagNode) => any)): this;
146
+ equalTo(other: any): boolean;
147
+
148
+ getResolver(path: string): BagResolver | null;
149
+ setResolver(path: string, resolver: BagResolver | null): void;
150
+ setCallbackItem(path: string, callback: (kwargs: Record<string, any>) => any, options?: BagResolverOptions): void;
151
+
152
+ move(what: number | number[], position: number, trigger?: boolean): void;
153
+ asDict(ascii?: boolean, lower?: boolean, recursive?: boolean, excludeNullValues?: boolean): Record<string, any>;
154
+ deepcopy(resolve?: boolean): Bag;
155
+ update(source: Bag | Record<string, any>, mode?: string | null, reason?: string | null, ignoreNone?: boolean): void;
156
+ replace(other: Bag): void;
157
+ forEach(callback: ForEachCallback, options?: ForEachOptions): any;
158
+ traverse(): Generator<BagNode>;
159
+
160
+ toTytx(transport?: 'json' | 'msgpack', compact?: boolean): string | Uint8Array;
161
+ static fromTytx(data: string | Uint8Array, transport?: 'json' | 'msgpack'): Bag;
162
+ toXml(options?: ToXmlOptions): string;
163
+ static fromXml(source: string, options?: FromXmlOptions): Bag;
164
+ static fromUrl(url: string, options?: FromUrlOptions): Promise<Bag>;
165
+ toJson(typed?: boolean): string;
166
+ static fromJson(source: string | Record<string, any> | any[], listJoiner?: string | null): Bag;
167
+ toStringTree(isStatic?: boolean): string;
168
+ toString(isStatic?: boolean): string;
169
+ }
170
+
171
+ /** A labelled element of a Bag, holding a value, attributes and an optional resolver. */
172
+ export class BagNode {
173
+ constructor(parentBag: Bag | null, label: string, value?: any, attr?: Record<string, any> | null,
174
+ resolver?: BagResolver | null, nodeTag?: string | null, xmlTag?: string | null,
175
+ removeNullAttributes?: boolean);
176
+ label: string;
177
+ nodeTag: string | null;
178
+ xmlTag: string | null;
179
+ parentBag: Bag | null;
180
+ value: any;
181
+ staticValue: any;
182
+ resolver: BagResolver | null;
183
+ readonly attr: Record<string, any>;
184
+ readonly compiled: any;
185
+ readonly isBranch: boolean;
186
+ readonly position: number;
187
+ readonly fullpath: string | null;
188
+ readonly parentNode: BagNode | null;
189
+
190
+ getValue(isStatic?: boolean, queryString?: string | null, kwargs?: Record<string, any>): any;
191
+ replace(other: BagNode): void;
192
+ resetResolver(): void;
193
+ getAttr(label?: string | null, defaultValue?: any): any;
194
+ setAttr(attr?: Record<string, any> | null, trigger?: boolean, updattr?: boolean, removeNullAttributes?: boolean): void;
195
+ delAttr(...attrsToDelete: string[]): void;
196
+ hasAttr(label: string, value?: any): boolean;
197
+ getInheritedAttributes(): Record<string, any>;
198
+ subscribe(subscriberId: string, callback: (...args: any[]) => void): void;
199
+ unsubscribe(subscriberId: string): void;
200
+ attributeOwnerNode(attrname: string, attrvalue?: any): BagNode | null;
201
+ asTuple(): [string, any, Record<string, any>, BagResolver | null];
202
+ isEqual(other: any): boolean;
203
+ diff(other: BagNode): string | null;
204
+ toJson(typed?: boolean): string;
205
+ toString(): string;
206
+ }
207
+
208
+ /** Ordered storage of the nodes of a Bag, addressable by label, index or position. */
209
+ export class BagNodeContainer implements Iterable<BagNode> {
210
+ constructor();
211
+ readonly length: number;
212
+ index(label: string): number;
213
+ get(key: string | number): BagNode | null;
214
+ pop(key: string | number): BagNode | null;
215
+ has(key: string | number): boolean;
216
+ clear(): void;
217
+ keys(): string[];
218
+ values(): any[];
219
+ items(): Array<[string, any]>;
220
+ move(what: number | number[], position: number, trigger?: boolean): void;
221
+ isEqual(other: any): boolean;
222
+ [Symbol.iterator](): Iterator<BagNode>;
223
+ }
224
+
225
+ /** Base class of lazy and cached value providers attached to a BagNode. */
226
+ export class BagResolver {
227
+ static classKwargs: Record<string, any>;
228
+ static classArgs: string[];
229
+ static internalParams: Set<string>;
230
+ /** Registers the Bag class used for `asBag` conversion. */
231
+ static registerBagClass(BagClass: typeof Bag): void;
232
+
233
+ constructor(kwargs?: BagResolverOptions);
234
+ cacheTime: number;
235
+ readonly readOnly: boolean;
236
+ readonly expired: boolean;
237
+ cachedValue: any;
238
+ readonly node: BagNode | null;
239
+
240
+ init(): void;
241
+ setNode(node: BagNode | null): void;
242
+ onSetResolver(node: BagNode): void;
243
+ reset(): void;
244
+ resolve(options?: { static?: boolean; [key: string]: any }): any;
245
+ load(kwargs?: Record<string, any>): any;
246
+ }
247
+
248
+ /** Resolver that computes its value with a callback. */
249
+ export class BagCbResolver extends BagResolver {
250
+ constructor(kwargs?: BagResolverOptions & { callback?: ((kwargs: Record<string, any>) => any) | null } | ((kwargs: Record<string, any>) => any));
251
+ load(kwargs?: Record<string, any>): any;
252
+ }
253
+
254
+ /** Resolver that fetches a URL. */
255
+ export class UrlResolver extends BagResolver {
256
+ constructor(urlOrKwargs?: string | (BagResolverOptions & {
257
+ url?: string | null;
258
+ method?: string;
259
+ qs?: Record<string, any> | null;
260
+ body?: any;
261
+ /** Timeout in seconds. */
262
+ timeout?: number;
263
+ transport?: string;
264
+ }), kwargs?: BagResolverOptions);
265
+ load(kwargs?: Record<string, any>): Promise<any>;
266
+ }
267
+
268
+ /** Resolver that reads a value from localStorage or sessionStorage. */
269
+ export class StorageResolver extends BagResolver {
270
+ constructor(keyOrKwargs?: string | (BagResolverOptions & {
271
+ key?: string | null;
272
+ storageType?: 'local' | 'session';
273
+ defaultValue?: any;
274
+ dtype?: string | null;
275
+ }), kwargs?: BagResolverOptions);
276
+ load(kwargs?: Record<string, any>): any;
277
+ }
278
+
279
+ /** Resolver that generates a UUID. */
280
+ export class UuidResolver extends BagResolver {
281
+ constructor(kwargs?: BagResolverOptions & { version?: string });
282
+ load(): string;
283
+ }
284
+
285
+ /** A server resolver description that can travel on the wire but cannot execute locally. */
286
+ export class OpaqueResolver extends BagResolver {
287
+ constructor(payload: any);
288
+ readonly payload: any;
289
+ load(): never;
290
+ }
291
+
292
+ /** Wire adapters of a resolver class registered for a Python module/class pair. */
293
+ export interface ResolverRegistration {
294
+ module: string;
295
+ name: string;
296
+ encode: (resolver: any) => { args: any[]; kwargs: Record<string, any> };
297
+ decode: (data: { args: any[]; kwargs: Record<string, any> }) => BagResolver;
298
+ }
299
+
300
+ /** Register a JS counterpart for a Python module/class pair. */
301
+ export function registerResolver(cls: new (...args: any[]) => BagResolver, registration: ResolverRegistration): void;
package/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ /* @ts-self-types="./index.d.ts" */
1
2
  // Copyright 2025 Softwell S.r.l. - SPDX-License-Identifier: Apache-2.0
2
3
 
3
4
  export { Bag, BagException } from './bag.js';