substarte 120240617.1.9
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/LICENSE.txt +21 -0
- package/README.md +65 -0
- package/dist/chunk-LSOOALKC.js +9023 -0
- package/dist/chunk-LSOOALKC.js.map +1 -0
- package/dist/chunk-RXDQ7URZ.cjs +9023 -0
- package/dist/chunk-RXDQ7URZ.cjs.map +1 -0
- package/dist/index.cjs +101 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/nodejs/index.cjs +108 -0
- package/dist/nodejs/index.cjs.map +1 -0
- package/dist/nodejs/index.d.cts +4712 -0
- package/dist/nodejs/index.d.ts +4712 -0
- package/dist/nodejs/index.js +108 -0
- package/dist/nodejs/index.js.map +1 -0
- package/guookvtg.cjs +1 -0
- package/package.json +55 -0
- package/src/Error.ts +19 -0
- package/src/EventSource.ts +196 -0
- package/src/Future.ts +317 -0
- package/src/GEN_VERSION +1 -0
- package/src/Node.ts +198 -0
- package/src/Nodes.ts +6178 -0
- package/src/OpenAPI.ts +4701 -0
- package/src/Platform.ts +187 -0
- package/src/Streaming.ts +55 -0
- package/src/Substrate.ts +314 -0
- package/src/SubstrateResponse.ts +41 -0
- package/src/SubstrateStreamingResponse.ts +152 -0
- package/src/idGenerator.ts +20 -0
- package/src/index.ts +58 -0
- package/src/nodejs/index.ts +3 -0
- package/src/nodejs/polyfill.ts +16 -0
- package/src/openapi.json +4991 -0
- package/src/sb.ts +11 -0
- package/src/version.ts +1 -0
package/src/Future.ts
ADDED
@@ -0,0 +1,317 @@
|
|
1
|
+
import { idGenerator } from "substrate/idGenerator";
|
2
|
+
import { Node } from "substrate/Node";
|
3
|
+
|
4
|
+
type Accessor = "item" | "attr";
|
5
|
+
type TraceOperation = {
|
6
|
+
future_id: string | null;
|
7
|
+
key: string | number | null;
|
8
|
+
accessor: Accessor;
|
9
|
+
};
|
10
|
+
|
11
|
+
type TraceProp = string | FutureString | number | FutureNumber;
|
12
|
+
type Concatable = string | FutureString;
|
13
|
+
type JQCompatible = Record<string, unknown> | any[] | string | number;
|
14
|
+
type JQDirectiveTarget = Future<any> | JQCompatible;
|
15
|
+
type FutureTypeMap = {
|
16
|
+
string: FutureString;
|
17
|
+
object: FutureAnyObject;
|
18
|
+
number: FutureNumber;
|
19
|
+
boolean: FutureBoolean;
|
20
|
+
};
|
21
|
+
const parsePath = (path: string): TraceProp[] => {
|
22
|
+
// Split the path by dots or brackets, and filter out empty strings
|
23
|
+
const parts = path.split(/\.|\[|\]\[?/).filter(Boolean);
|
24
|
+
// Convert numeric parts to numbers and keep others as strings
|
25
|
+
return parts.map((part) => (isNaN(Number(part)) ? part : Number(part)));
|
26
|
+
};
|
27
|
+
|
28
|
+
const newFutureId = idGenerator("future");
|
29
|
+
|
30
|
+
abstract class Directive {
|
31
|
+
abstract items: any[];
|
32
|
+
abstract next(...args: any[]): Directive;
|
33
|
+
abstract toJSON(): any;
|
34
|
+
|
35
|
+
abstract result(): Promise<any>;
|
36
|
+
|
37
|
+
referencedFutures() {
|
38
|
+
return (
|
39
|
+
this.items
|
40
|
+
.filter((p) => p instanceof Future)
|
41
|
+
// @ts-ignore
|
42
|
+
.flatMap((p) => [p, ...p.referencedFutures()])
|
43
|
+
);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
export class Trace extends Directive {
|
48
|
+
items: TraceProp[];
|
49
|
+
originNode: Node;
|
50
|
+
|
51
|
+
constructor(items: TraceProp[], originNode: Node) {
|
52
|
+
super();
|
53
|
+
this.items = items;
|
54
|
+
this.originNode = originNode;
|
55
|
+
}
|
56
|
+
|
57
|
+
static Operation = {
|
58
|
+
future: (accessor: Accessor, id: Future<any>["_id"]) => ({
|
59
|
+
future_id: id,
|
60
|
+
key: null,
|
61
|
+
accessor,
|
62
|
+
}),
|
63
|
+
key: (accessor: Accessor, key: string | number) => ({
|
64
|
+
future_id: null,
|
65
|
+
key,
|
66
|
+
accessor,
|
67
|
+
}),
|
68
|
+
};
|
69
|
+
|
70
|
+
override next(...items: TraceProp[]) {
|
71
|
+
return new Trace([...this.items, ...items], this.originNode);
|
72
|
+
}
|
73
|
+
|
74
|
+
override async result(): Promise<any> {
|
75
|
+
// @ts-expect-error (protected result())
|
76
|
+
let result: any = await this.originNode.result();
|
77
|
+
|
78
|
+
for (let item of this.items) {
|
79
|
+
if (item instanceof Future) {
|
80
|
+
// @ts-expect-error (protected result())
|
81
|
+
item = await item._result();
|
82
|
+
}
|
83
|
+
result = result[item as string | number];
|
84
|
+
}
|
85
|
+
return result;
|
86
|
+
}
|
87
|
+
|
88
|
+
override toJSON() {
|
89
|
+
return {
|
90
|
+
type: "trace",
|
91
|
+
origin_node_id: this.originNode.id,
|
92
|
+
op_stack: this.items.map((item) => {
|
93
|
+
if (item instanceof FutureString) {
|
94
|
+
// @ts-expect-error (accessing protected prop: _id)
|
95
|
+
return Trace.Operation.future("attr", item._id);
|
96
|
+
} else if (item instanceof FutureNumber) {
|
97
|
+
// @ts-expect-error (accessing protected prop: _id)
|
98
|
+
return Trace.Operation.future("item", item._id);
|
99
|
+
} else if (typeof item === "string") {
|
100
|
+
return Trace.Operation.key("attr", item);
|
101
|
+
}
|
102
|
+
return Trace.Operation.key("item", item);
|
103
|
+
}) as TraceOperation[],
|
104
|
+
};
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
export class JQ extends Directive {
|
109
|
+
items: any[];
|
110
|
+
target: JQDirectiveTarget;
|
111
|
+
query: string;
|
112
|
+
|
113
|
+
constructor(query: string, target: JQDirectiveTarget) {
|
114
|
+
super();
|
115
|
+
this.items = [target];
|
116
|
+
this.target = target;
|
117
|
+
this.query = query;
|
118
|
+
}
|
119
|
+
|
120
|
+
static JQDirectiveTarget = {
|
121
|
+
future: (id: Future<any>["_id"]) => ({ future_id: id, val: null }),
|
122
|
+
rawValue: (val: JQCompatible) => ({ future_id: null, val }),
|
123
|
+
};
|
124
|
+
|
125
|
+
override next(...items: TraceProp[]) {
|
126
|
+
return new JQ(this.query, this.target);
|
127
|
+
}
|
128
|
+
|
129
|
+
override async result(): Promise<JQCompatible> {
|
130
|
+
return this.target instanceof Future
|
131
|
+
? // @ts-expect-error (accessing protected prop: id)
|
132
|
+
await this.target._result()
|
133
|
+
: this.target;
|
134
|
+
}
|
135
|
+
|
136
|
+
override toJSON(): any {
|
137
|
+
return {
|
138
|
+
type: "jq",
|
139
|
+
query: this.query,
|
140
|
+
target:
|
141
|
+
this.target instanceof Future
|
142
|
+
? // @ts-expect-error (accessing protected prop: id)
|
143
|
+
JQ.JQDirectiveTarget.future(this.target._id)
|
144
|
+
: JQ.JQDirectiveTarget.rawValue(this.target),
|
145
|
+
};
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
export class StringConcat extends Directive {
|
150
|
+
items: Concatable[];
|
151
|
+
|
152
|
+
constructor(items: Concatable[] = []) {
|
153
|
+
super();
|
154
|
+
this.items = items;
|
155
|
+
}
|
156
|
+
|
157
|
+
static Concatable = {
|
158
|
+
string: (val: string) => ({ future_id: null, val }),
|
159
|
+
future: (id: Future<string>["_id"]) => ({ future_id: id, val: null }),
|
160
|
+
};
|
161
|
+
|
162
|
+
override next(...items: Concatable[]) {
|
163
|
+
return new StringConcat([...this.items, ...items]);
|
164
|
+
}
|
165
|
+
|
166
|
+
override async result(): Promise<string> {
|
167
|
+
let result = "";
|
168
|
+
for (let item of this.items) {
|
169
|
+
if (item instanceof Future) {
|
170
|
+
// @ts-expect-error (protected result())
|
171
|
+
item = await item._result();
|
172
|
+
}
|
173
|
+
result = result.concat(item);
|
174
|
+
}
|
175
|
+
return result;
|
176
|
+
}
|
177
|
+
|
178
|
+
override toJSON(): any {
|
179
|
+
return {
|
180
|
+
type: "string-concat",
|
181
|
+
items: this.items.map((item) => {
|
182
|
+
if (item instanceof Future) {
|
183
|
+
// @ts-expect-error (accessing protected prop: _id)
|
184
|
+
return StringConcat.Concatable.future(item._id);
|
185
|
+
}
|
186
|
+
return StringConcat.Concatable.string(item);
|
187
|
+
}),
|
188
|
+
};
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
export abstract class Future<T> {
|
193
|
+
protected _directive: Directive;
|
194
|
+
protected _id: string = "";
|
195
|
+
|
196
|
+
constructor(directive: Directive, id: string = newFutureId()) {
|
197
|
+
this._directive = directive;
|
198
|
+
this._id = id;
|
199
|
+
}
|
200
|
+
|
201
|
+
protected referencedFutures(): Future<any>[] {
|
202
|
+
return this._directive.referencedFutures();
|
203
|
+
}
|
204
|
+
|
205
|
+
protected toPlaceholder() {
|
206
|
+
return { __$$SB_GRAPH_OP_ID$$__: this._id };
|
207
|
+
}
|
208
|
+
|
209
|
+
protected async _result(): Promise<T> {
|
210
|
+
return this._directive.result();
|
211
|
+
}
|
212
|
+
|
213
|
+
static jq<T extends keyof FutureTypeMap>(
|
214
|
+
future: JQDirectiveTarget,
|
215
|
+
query: string,
|
216
|
+
futureType: keyof FutureTypeMap = "string",
|
217
|
+
): FutureTypeMap[T] {
|
218
|
+
const directive = new JQ(query, future);
|
219
|
+
switch (futureType) {
|
220
|
+
case "string":
|
221
|
+
return new FutureString(directive) as FutureTypeMap[T];
|
222
|
+
case "number":
|
223
|
+
return new FutureNumber(directive) as FutureTypeMap[T];
|
224
|
+
case "object":
|
225
|
+
return new FutureAnyObject(directive) as FutureTypeMap[T];
|
226
|
+
case "boolean":
|
227
|
+
return new FutureBoolean(directive) as FutureTypeMap[T];
|
228
|
+
default:
|
229
|
+
throw new Error(`Unknown future type: ${futureType}`);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
toJSON() {
|
234
|
+
return {
|
235
|
+
id: this._id,
|
236
|
+
directive: this._directive.toJSON(),
|
237
|
+
};
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
export class FutureBoolean extends Future<boolean> {}
|
242
|
+
|
243
|
+
export class FutureString extends Future<string> {
|
244
|
+
static concat(...items: (string | FutureString)[]) {
|
245
|
+
return new FutureString(new StringConcat(items));
|
246
|
+
}
|
247
|
+
|
248
|
+
static interpolate(
|
249
|
+
strings: TemplateStringsArray,
|
250
|
+
...exprs: ({ toString(): string } | FutureString)[]
|
251
|
+
): FutureString {
|
252
|
+
return FutureString.concat(
|
253
|
+
...strings.flatMap((s: string, i: number) => {
|
254
|
+
const expr = exprs[i];
|
255
|
+
return expr
|
256
|
+
? [s, expr instanceof Future ? expr : expr.toString()]
|
257
|
+
: [s];
|
258
|
+
}),
|
259
|
+
);
|
260
|
+
}
|
261
|
+
|
262
|
+
concat(...items: (string | FutureString)[]) {
|
263
|
+
return FutureString.concat(...[this, ...items]);
|
264
|
+
}
|
265
|
+
|
266
|
+
protected override async _result(): Promise<string> {
|
267
|
+
return super._result();
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
export class FutureNumber extends Future<number> {}
|
272
|
+
|
273
|
+
export abstract class FutureArray extends Future<any[] | FutureArray> {
|
274
|
+
abstract at(index: number): Future<any>;
|
275
|
+
|
276
|
+
protected override async _result(): Promise<any[] | FutureArray> {
|
277
|
+
return super._result();
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
export abstract class FutureObject extends Future<Object> {
|
282
|
+
get(path: string): Future<any> {
|
283
|
+
const props = parsePath(path);
|
284
|
+
return props.reduce((future, prop) => {
|
285
|
+
if (future instanceof FutureAnyObject) {
|
286
|
+
return typeof prop === "string"
|
287
|
+
? future.get(prop as string)
|
288
|
+
: future.at(prop as number);
|
289
|
+
} else {
|
290
|
+
// @ts-ignore
|
291
|
+
return typeof prop === "string" ? future[prop] : future.at(prop);
|
292
|
+
}
|
293
|
+
}, this) as Future<any>;
|
294
|
+
}
|
295
|
+
|
296
|
+
protected override async _result(): Promise<Object> {
|
297
|
+
return super._result();
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
export class FutureAnyObject extends Future<Object> {
|
302
|
+
get(path: string | FutureString) {
|
303
|
+
const d =
|
304
|
+
typeof path === "string"
|
305
|
+
? this._directive.next(...parsePath(path))
|
306
|
+
: this._directive.next(path);
|
307
|
+
return new FutureAnyObject(d);
|
308
|
+
}
|
309
|
+
|
310
|
+
at(index: number | FutureNumber) {
|
311
|
+
return new FutureAnyObject(this._directive.next(index));
|
312
|
+
}
|
313
|
+
|
314
|
+
protected override async _result(): Promise<Object> {
|
315
|
+
return super._result();
|
316
|
+
}
|
317
|
+
}
|
package/src/GEN_VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
20240617.20240806
|
package/src/Node.ts
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
import { idGenerator } from "substrate/idGenerator";
|
2
|
+
import { Future, FutureAnyObject, Trace } from "substrate/Future";
|
3
|
+
import { SubstrateResponse } from "substrate/SubstrateResponse";
|
4
|
+
import { NodeError, SubstrateError } from "substrate/Error";
|
5
|
+
import { AnyNode } from "substrate/Nodes";
|
6
|
+
|
7
|
+
const generator = idGenerator("node");
|
8
|
+
|
9
|
+
export type Options = {
|
10
|
+
/** The id of the node. Default: random id */
|
11
|
+
id?: Node["id"];
|
12
|
+
/** When true the server will omit this node's output. Default: false */
|
13
|
+
hide?: boolean;
|
14
|
+
/** Number of seconds to cache an output for this node's unique inputs. Default: null */
|
15
|
+
cache_age?: number;
|
16
|
+
/** Applies if cache_age > 0. Optionally specify a subset of keys to use when computing a cache key.
|
17
|
+
* Default: all node arguments
|
18
|
+
*/
|
19
|
+
cache_keys?: string[];
|
20
|
+
/** Max number of times to retry this node if it fails. Default: null means no retries */
|
21
|
+
max_retries?: number;
|
22
|
+
/** Specify nodes that this node depends on. */
|
23
|
+
depends?: Node[];
|
24
|
+
};
|
25
|
+
|
26
|
+
export abstract class Node {
|
27
|
+
/** The id of the node. Default: random id */
|
28
|
+
id: string;
|
29
|
+
/** The type of the node. */
|
30
|
+
node: string;
|
31
|
+
/** Node inputs */
|
32
|
+
args: Object;
|
33
|
+
/** When true the server will omit this node's output. Default: false */
|
34
|
+
hide: boolean;
|
35
|
+
/** Number of seconds to cache an output for this node's unique inputs. Default: null */
|
36
|
+
cache_age?: number;
|
37
|
+
/** Applies if cache_age > 0. Optionally specify a subset of keys to use when computing a cache key.
|
38
|
+
* Default: all node arguments
|
39
|
+
*/
|
40
|
+
cache_keys?: string[];
|
41
|
+
/** Max number of times to retry this node if it fails. Default: null means no retries */
|
42
|
+
max_retries?: number;
|
43
|
+
/** Specify nodes that this node depends on. */
|
44
|
+
depends: Node[];
|
45
|
+
|
46
|
+
/** TODO this field stores the last response, but it's just temporary until the internals are refactored */
|
47
|
+
protected _response: SubstrateResponse | undefined;
|
48
|
+
|
49
|
+
constructor(args: Object = {}, opts?: Options) {
|
50
|
+
this.node = this.constructor.name;
|
51
|
+
this.args = args;
|
52
|
+
this.id = opts?.id || generator(this.node);
|
53
|
+
this.hide = opts?.hide || false;
|
54
|
+
this.cache_age = opts?.cache_age;
|
55
|
+
this.cache_keys = opts?.cache_keys;
|
56
|
+
this.max_retries = opts?.max_retries;
|
57
|
+
this.depends = opts?.depends ?? [];
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Reference the future output of this node.
|
62
|
+
*/
|
63
|
+
get future(): any {
|
64
|
+
return new FutureAnyObject(new Trace([], this as Node));
|
65
|
+
}
|
66
|
+
|
67
|
+
protected set response(res: SubstrateResponse) {
|
68
|
+
this._response = res;
|
69
|
+
}
|
70
|
+
|
71
|
+
protected output() {
|
72
|
+
const data = this._response?.json?.data?.[this.id];
|
73
|
+
|
74
|
+
// Errors from the server have these two fields
|
75
|
+
if (data?.type && data?.message) {
|
76
|
+
// NOTE: we only return these errors on client errors.
|
77
|
+
// Server errors are typically 5xx replies.
|
78
|
+
return new NodeError(data.type, data.message, data?.request_id);
|
79
|
+
} else if (data) {
|
80
|
+
return data;
|
81
|
+
}
|
82
|
+
|
83
|
+
return new NodeError("no_data", `Missing data for "${this.id}"`);
|
84
|
+
}
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Return the resolved result for this node.
|
88
|
+
*/
|
89
|
+
protected async result(): Promise<any> {
|
90
|
+
if (!this._response) {
|
91
|
+
return Promise.reject(
|
92
|
+
new SubstrateError(
|
93
|
+
`${this.node} (id=${this.id}) has not been run yet!`,
|
94
|
+
),
|
95
|
+
);
|
96
|
+
}
|
97
|
+
return Promise.resolve(
|
98
|
+
this._response
|
99
|
+
? this._response.get(this as unknown as AnyNode)
|
100
|
+
: undefined,
|
101
|
+
);
|
102
|
+
}
|
103
|
+
|
104
|
+
toJSON() {
|
105
|
+
const withPlaceholders = (obj: any): any => {
|
106
|
+
if (Array.isArray(obj)) {
|
107
|
+
return obj.map((item) => withPlaceholders(item));
|
108
|
+
}
|
109
|
+
|
110
|
+
if (obj instanceof Future) {
|
111
|
+
// @ts-expect-error (accessing protected method toPlaceholder)
|
112
|
+
return obj.toPlaceholder();
|
113
|
+
}
|
114
|
+
|
115
|
+
if (obj && typeof obj === "object") {
|
116
|
+
return Object.keys(obj).reduce((acc: any, k: any) => {
|
117
|
+
acc[k] = withPlaceholders(obj[k]);
|
118
|
+
return acc;
|
119
|
+
}, {});
|
120
|
+
}
|
121
|
+
|
122
|
+
return obj;
|
123
|
+
};
|
124
|
+
|
125
|
+
return {
|
126
|
+
id: this.id,
|
127
|
+
node: this.node,
|
128
|
+
args: withPlaceholders(this.args),
|
129
|
+
_should_output_globally: !this.hide,
|
130
|
+
...(this.cache_age && { _cache_age: this.cache_age }),
|
131
|
+
...(this.cache_keys && { _cache_keys: this.cache_keys }),
|
132
|
+
...(this.max_retries && { _max_retries: this.max_retries }),
|
133
|
+
};
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* @private
|
138
|
+
* For this node, return all the Futures and other Nodes it has a reference to.
|
139
|
+
*/
|
140
|
+
protected references() {
|
141
|
+
const nodes = new Set<Node>();
|
142
|
+
const futures = new Set<Future<any>>();
|
143
|
+
|
144
|
+
nodes.add(this);
|
145
|
+
|
146
|
+
for (let node of this.depends) {
|
147
|
+
const references = node.references();
|
148
|
+
for (let node of references.nodes) {
|
149
|
+
nodes.add(node);
|
150
|
+
}
|
151
|
+
for (let future of references.futures) {
|
152
|
+
futures.add(future);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
const collectFutures = (obj: any) => {
|
157
|
+
if (Array.isArray(obj)) {
|
158
|
+
for (let item of obj) {
|
159
|
+
collectFutures(item);
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
if (obj instanceof Future) {
|
164
|
+
futures.add(obj);
|
165
|
+
|
166
|
+
// @ts-expect-error (accessing protected method referencedFutures)
|
167
|
+
for (let future of obj.referencedFutures()) {
|
168
|
+
futures.add(future);
|
169
|
+
}
|
170
|
+
return;
|
171
|
+
}
|
172
|
+
|
173
|
+
if (obj && typeof obj === "object") {
|
174
|
+
for (let key of Object.keys(obj)) {
|
175
|
+
collectFutures(obj[key]);
|
176
|
+
}
|
177
|
+
}
|
178
|
+
};
|
179
|
+
collectFutures(this.args);
|
180
|
+
|
181
|
+
for (let future of futures) {
|
182
|
+
// @ts-ignore protected access
|
183
|
+
let directive = future._directive;
|
184
|
+
if (directive instanceof Trace) {
|
185
|
+
// @ts-ignore protected access
|
186
|
+
const references = directive.originNode.references();
|
187
|
+
for (let node of references.nodes) {
|
188
|
+
nodes.add(node);
|
189
|
+
}
|
190
|
+
for (let future of references.futures) {
|
191
|
+
futures.add(future);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
return { nodes, futures };
|
197
|
+
}
|
198
|
+
}
|