runtime-type-inspector 1.0.0 → 2.0.0

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.
Files changed (54) hide show
  1. package/.eslintrc.js +480 -0
  2. package/README.md +12 -4
  3. package/jsconfig.json +10 -0
  4. package/package.json +32 -4
  5. package/plugin-parcel/index.mjs +4 -0
  6. package/plugin-rollup/index.mjs +78 -0
  7. package/plugin-webpack/index.mjs +4 -0
  8. package/rollup.config.mjs +183 -0
  9. package/src-runtime/assertType.mjs +54 -0
  10. package/src-runtime/createDiv.mjs +69 -0
  11. package/src-runtime/index.mjs +21 -0
  12. package/src-runtime/makeJSDoc.mjs +40 -0
  13. package/src-runtime/registerClass.mjs +11 -0
  14. package/src-runtime/registerTypedef.mjs +12 -0
  15. package/src-runtime/typecheckDiv.mjs +3 -0
  16. package/src-runtime/typecheckEvery.mjs +21 -0
  17. package/src-runtime/typecheckOptions.mjs +60 -0
  18. package/src-runtime/typecheckTable.mjs +14 -0
  19. package/src-runtime/typecheckWarn.mjs +23 -0
  20. package/src-runtime/validateArray.mjs +26 -0
  21. package/src-runtime/validateDivision.mjs +31 -0
  22. package/src-runtime/validateMap.mjs +36 -0
  23. package/src-runtime/validateNumber.mjs +29 -0
  24. package/src-runtime/validateObject.mjs +43 -0
  25. package/src-runtime/validateRecord.mjs +31 -0
  26. package/src-runtime/validateSet.mjs +26 -0
  27. package/src-runtime/validateTuple.mjs +28 -0
  28. package/src-runtime/validateType.mjs +214 -0
  29. package/src-runtime/validateTypedef.mjs +18 -0
  30. package/src-runtime/validateUnion.mjs +19 -0
  31. package/src-runtime/youCanAddABreakpointHere.mjs +11 -0
  32. package/src-transpiler/Stringifier.mjs +1268 -0
  33. package/src-transpiler/StringifierWithTypeAssertions.mjs +478 -0
  34. package/src-transpiler/addTypeChecks.mjs +20 -0
  35. package/src-transpiler/ast2json.mjs +13 -0
  36. package/src-transpiler/ast2jsonForComparison.mjs +28 -0
  37. package/src-transpiler/code2ast2code.mjs +16 -0
  38. package/src-transpiler/expandType.mjs +187 -0
  39. package/src-transpiler/expandTypeDepFree.mjs +122 -0
  40. package/src-transpiler/extractNameAndOptionality.mjs +23 -0
  41. package/src-transpiler/index.mjs +13 -0
  42. package/src-transpiler/parseJSDoc.mjs +69 -0
  43. package/src-transpiler/parseJSDocSetter.mjs +16 -0
  44. package/src-transpiler/parseJSDocTypedef.mjs +69 -0
  45. package/src-transpiler/simplifyType.mjs +31 -0
  46. package/src-transpiler/stat.mjs +13 -0
  47. package/ui/babel-core.mjs +5 -0
  48. package/ui/babel-helper-plugin-utils.mjs +7 -0
  49. package/ui/babel-parser.mjs +8 -0
  50. package/ui/babel-plugin-syntax-typescript.mjs +58 -0
  51. package/ui/importmap.js +38 -0
  52. package/ui/index.html +30 -0
  53. package/ui/index.mjs +379 -0
  54. package/src/index.mjs +0 -1
@@ -0,0 +1,187 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * @todo implement TypeQuery, e.g. for expandType('typeof Number');
4
+ * @example
5
+ * const { expandType } = await import("./src-transpiler/expandType.mjs");
6
+ * expandType('[string, Array|AnyTypedArray, number[]]|[ONNXTensor]');
7
+ * expandType('(123) '); // Outputs: '123'
8
+ * expandType(' ( ( 123 ) ) '); // Outputs: '123'
9
+ * expandType('Array<number> '); // Outputs: {type: 'array', elementType: 'number'}
10
+ * expandType('Array<(123) > '); // Outputs: {type: 'array', elementType: '123'}
11
+ * expandType('Array<"abc" | 123> '); // Outputs: {type: 'array', elementType: { type: 'union', members: [ '"abc"', '123' ]}}
12
+ * expandType(' (string ) |(number ) '); // Outputs: {type: 'union', members: [ 'string', 'number']}
13
+ * expandType(' "apples" | ( "bananas") '); // Outputs: {type: 'union', members: [ '"apples"', '"bananas"']}
14
+ * expandType('123? '); // Outputs: {"type":"union","members":["123","null"]}
15
+ * expandType('123|null '); // Outputs: {"type":"union","members":["123","null"]}
16
+ * expandType('Map<string, any>');
17
+ * @param {string} type
18
+ */
19
+ function expandType(type) {
20
+ const ast = parseType(type);
21
+ return toSourceTS(ast);
22
+ }
23
+ /**
24
+ * @typedef TypeScriptType
25
+ * @property {object[]|undefined} typeArguments
26
+ * @property {*} typeName
27
+ * @property {number} kind
28
+ */
29
+ /**
30
+ * @param {string} str - The type string.
31
+ * @returns {TypeScriptType}
32
+ */
33
+ function parseType(str) {
34
+ // TS doesn't like ... notation in this context
35
+ if (str.startsWith('...')) {
36
+ str = str.slice(3); // remove dots
37
+ str += '[]'; // turn into array
38
+ }
39
+ // type tmp = (...string) => 123; to have a function context
40
+ str = `type tmp = ${str};`;
41
+ const ast = ts.createSourceFile('repl.ts', str, ts.ScriptTarget.Latest, true /*setParentNodes*/);
42
+ return ast.statements[0].type;
43
+ }
44
+ /**
45
+ * @param {TypeScriptType} node
46
+ * @returns
47
+ */
48
+ function toSourceTS(node) {
49
+ const {typeArguments, typeName} = node;
50
+ const kind_ = ts.SyntaxKind[node.kind];
51
+ const {
52
+ AnyKeyword, ArrayType, BooleanKeyword, FunctionType, Identifier, IntersectionType,
53
+ JSDocAllType, LastTypeNode, LiteralType, NullKeyword, NumberKeyword, NumericLiteral,
54
+ ObjectKeyword, Parameter, ParenthesizedType, PropertySignature, StringKeyword,
55
+ StringLiteral, ThisType, TupleType, TypeLiteral, TypeReference, UndefinedKeyword,
56
+ UnionType, JSDocNullableType,
57
+ } = ts.SyntaxKind;
58
+ // console.log({ typeArguments, typeName, kind_, node });
59
+ switch (node.kind) {
60
+ case FunctionType:
61
+ const parameters = node.parameters.map(toSourceTS);
62
+ return {type: 'function', parameters};
63
+ case JSDocNullableType:
64
+ const t = toSourceTS(node.type);
65
+ return {type: 'union', members: [t, 'null']};
66
+ // todo work out more: const jsdoc = `(...a: ...number) => 123
67
+ // TS even thinks it's two parameters... just go for array/[]
68
+ case Parameter:
69
+ const type = node.type ? toSourceTS(node.type) : 'any';
70
+ const name = toSourceTS(node.name);
71
+ const ret = {type, name};
72
+ if (node.dotDotDotToken) {
73
+ return {type: 'array', elementType: ret};
74
+ }
75
+ return ret;
76
+ case TypeReference:
77
+ if ((typeName.text === 'Object' || typeName.text === 'Record') && typeArguments?.length === 2) {
78
+ return {
79
+ type: 'record',
80
+ key: toSourceTS(typeArguments[0]),
81
+ val: toSourceTS(typeArguments[1]),
82
+ };
83
+ } else if (typeName.text === 'Object' && (!typeArguments || typeArguments?.length === 0)) {
84
+ return {type: 'object', properties: {}};
85
+ } else if (typeName.text === 'Map' && typeArguments?.length === 2) {
86
+ return {
87
+ type: 'map',
88
+ key: toSourceTS(typeArguments[0]),
89
+ val: toSourceTS(typeArguments[1]),
90
+ };
91
+ } else if (typeName.text === 'Array' && typeArguments?.length === 1) {
92
+ const elementType = toSourceTS(typeArguments[0]);
93
+ return {type: 'array', elementType};
94
+ } else if (typeName.text === 'Set' && typeArguments?.length === 1) {
95
+ const elementType = toSourceTS(typeArguments[0]);
96
+ return {type: 'set', elementType};
97
+ } else if (typeName.text === 'Class' && typeArguments?.length === 1) {
98
+ return {
99
+ type: 'class',
100
+ elementType: toSourceTS(typeArguments[0])
101
+ }
102
+ } else {
103
+ if (!typeArguments) {
104
+ return typeName.getText();
105
+ }
106
+ console.warn('unhandled TypeReference', kind_, node);
107
+ return {
108
+ type: 'unhandled TypeReference'
109
+ };
110
+ }
111
+ break;
112
+ case StringKeyword:
113
+ return node.getText();
114
+ case NumberKeyword:
115
+ return node.getText();
116
+ case IntersectionType:
117
+ return {
118
+ type: 'intersection',
119
+ members: node.types.map(toSourceTS)
120
+ }
121
+ case TupleType:
122
+ return {
123
+ type: 'tuple',
124
+ elements: node.elements.map(toSourceTS)
125
+ }
126
+ case UnionType:
127
+ return {
128
+ type: 'union',
129
+ members: node.types.map(toSourceTS)
130
+ }
131
+ case TypeLiteral:
132
+ const properties = {};
133
+ node.members.forEach(member => {
134
+ const name = toSourceTS(member.name);
135
+ const type = toSourceTS(member.type);
136
+ properties[name] = type;
137
+ });
138
+ return {
139
+ type: 'object',
140
+ properties
141
+ }
142
+ case PropertySignature:
143
+ console.warn('toSourceTS> should not happen, handled by TypeLiteral directly');
144
+ return `${toSourceTS(node.name)}: ${toSourceTS(node.type)}`;
145
+ case Identifier:
146
+ return node.text;
147
+ case ArrayType:
148
+ return {
149
+ type: 'array',
150
+ elementType: toSourceTS(node.elementType)
151
+ };
152
+ case LiteralType:
153
+ return toSourceTS(node.literal);
154
+ case AnyKeyword:
155
+ case BooleanKeyword:
156
+ case JSDocAllType:
157
+ case NullKeyword:
158
+ case NumericLiteral:
159
+ case StringLiteral:
160
+ case ThisType:
161
+ case UndefinedKeyword:
162
+ return node.getText();
163
+ case ObjectKeyword:
164
+ return {
165
+ type: 'object',
166
+ properties: {}
167
+ }
168
+ case ParenthesizedType:
169
+ // fall-through for parentheses
170
+ return toSourceTS(node.type);
171
+ case LastTypeNode:
172
+ return toSourceTS(node.qualifier);
173
+ default:
174
+ // const test = {};
175
+ // Object.entries(ts.SyntaxKind).forEach(([name, id]) => {
176
+ // test[id] = (test[id] || []);
177
+ // test[id].push(name);
178
+ // });
179
+ // console.log(test);
180
+ console.warn('toSourceTS> unhandled kind - make sure to understand you cannot reverse TS enums');
181
+ console.warn('if they contain range aliases, for example:');
182
+ console.warn('ts.SyntaxKind.NumericLiteral === ts.SyntaxKind.FirstLiteralToken');
183
+ console.warn('so this "kind" could be wrong, but requires handling anyway:', kind_, node);
184
+ debugger;
185
+ }
186
+ }
187
+ export {expandType, parseType, toSourceTS};
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @todo expandTypeDepFree doesn't support "complicated" types.
3
+ * For actual builds, we use expandType() anyway (which is based on TypeScript).
4
+ * But since TypeScript is a huge dependency, I'm looking into BabelFlow/BabelTypescript parser.
5
+ * Comparing AST's like this usually helps to find bugs or potential issues,
6
+ * while we can benchmark for best performance too.
7
+ * @example
8
+ * const tooComplex = 'Array<string|{chunks?: undefined|Array<{language: string|null, timestamp: Array<number|null>, text: string}>}>';
9
+ * console.log(expandTypeDepFree(tooComplex));
10
+ */
11
+ /**
12
+ * @typedef {object} ExpandTypeReturnValue
13
+ * @property {'array' | 'union' | 'record' | 'tuple' | 'object'} type
14
+ * @property {object | string} [elementType]
15
+ * @property {object | string} [key]
16
+ * @property {object | string} [val]
17
+ * @property {(object | string)[]} [members] - For unions.
18
+ * @property {object | string} [properties] - For objects.
19
+ * @property {(object | string)[]} [elements] - For tuples.
20
+ */
21
+ /**
22
+ * 'DepFree' refers to the fact that this function has no dependencies,
23
+ * while `expandType` depends on TypeScript itself for maximum compatibility.
24
+ * @example
25
+ * expandTypeDepFree('(123) '); // Outputs: '123'
26
+ * expandTypeDepFree('Array<number> '); // Outputs: { type: 'array', elementType: 'number' }
27
+ * expandTypeDepFree('Array<(123) > '); // Outputs: { type: 'array', elementType: '123' }
28
+ * expandTypeDepFree(' ( ( 123 ) ) '); // Outputs: '123'
29
+ * expandTypeDepFree(' (string ) |(number ) '); // Outputs: { type: 'union', members: ['string', 'number'] }
30
+ * expandTypeDepFree(' (( Object ) ) '); // Outputs: { type: 'object', properties: {} }
31
+ * @param {string} type
32
+ * @returns {string | ExpandTypeReturnValue} Object containing parsed information from type string.
33
+ */
34
+ function expandTypeDepFree(type) {
35
+ type = type.trim();
36
+ // '(123)' -> '123'
37
+ while (!type.includes('|') && type[0] == '(' && type[type.length - 1] == ')') {
38
+ type = type.slice(1, -1).trim();
39
+ }
40
+ // (1) Rest parameters like ...string
41
+ if (type[0] === '.' && type[1] === '.' && type[2] === '.') {
42
+ return {
43
+ type: 'array',
44
+ elementType: type.slice(3)
45
+ }
46
+ }
47
+ // (2) Array<...>
48
+ if (type.startsWith("Array<") && type.endsWith('>')) {
49
+ const typeSlice = type.slice(6, -1);
50
+ return {
51
+ type: "array",
52
+ elementType: expandTypeDepFree(typeSlice)
53
+ }
54
+ }
55
+ // (3) Object<...> or Record<...>
56
+ if (
57
+ (
58
+ type.startsWith("Object<") ||
59
+ type.startsWith("Record<")
60
+ ) && type.endsWith('>')) {
61
+ const recordSlice = type.slice(7, -1);
62
+ const firstComma = recordSlice.indexOf(',');
63
+ if (firstComma === -1) {
64
+ console.warn("expandTypeDepFree> invalid Object/Record");
65
+ }
66
+ const key = recordSlice.slice(0, firstComma).trim();
67
+ const val = recordSlice.slice(firstComma + 1).trim();
68
+ return {
69
+ type: "record",
70
+ key: expandTypeDepFree(key),
71
+ val: expandTypeDepFree(val),
72
+ }
73
+ }
74
+ // (4) {...}
75
+ if (type[0] == '{' && type[type.length - 1] == '}') {
76
+ const propertiesArray = type.slice(1, -1).split(','); // ['entity: Entity', ' app: AppBase']
77
+ const properties = {};
78
+ propertiesArray.forEach(_ => {
79
+ const [propName, propType] = _.split(":").map(_=>_.trim());
80
+ if (!propName || !propType) {
81
+ console.warn('expandTypeDepFree> unexpected type format, fix');
82
+ return false;
83
+ }
84
+ properties[propName] = propType;
85
+ });
86
+ return {type: 'object', properties};
87
+ }
88
+ // (5) expand unions
89
+ const members = type.split("|");
90
+ if (members.length >= 2) {
91
+ members.forEach((_, i) => members[i]=_.trim());
92
+ return {
93
+ type: 'union',
94
+ members: members.map(expandTypeDepFree),
95
+ }
96
+ }
97
+ // (6) expand [] Arrays
98
+ // Test arrays: new pc.Mat3().set([1, 2, 3, "asd"])
99
+ if (type.endsWith("[]")) {
100
+ const typeSlice = type.slice(0, -2);
101
+ return {
102
+ type: 'array',
103
+ elementType: expandTypeDepFree(typeSlice)
104
+ }
105
+ }
106
+ // (7) expand tuples
107
+ if (type[0] == '[' && type[type.length - 1] == ']') {
108
+ const elements = type.slice(1, -1).split(','); // ['null', ' Texture', ' Texture', ' Texture', ' Texture', ' Texture', ' Texture']
109
+ return {
110
+ type: 'tuple',
111
+ elements: elements.map(expandTypeDepFree)
112
+ }
113
+ }
114
+ if (type === 'object' || type === 'Object') {
115
+ return {
116
+ type: 'object',
117
+ properties: {},
118
+ }
119
+ }
120
+ return type;
121
+ }
122
+ export {expandTypeDepFree};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @param {string} rest
3
+ * @returns {[string, boolean]}
4
+ */
5
+ function extractNameAndOptionality(rest) {
6
+ rest = rest.trim();
7
+ let optional = false;
8
+ // Examples:
9
+ // name: [kwargs={}] The configuration parameters.
10
+ // name: [d = 1.0] Sample spacing
11
+ if (rest[0] === '[') {
12
+ // Possible improvement: counting opening/closing brackets for perfect match
13
+ const closer = rest.lastIndexOf(']');
14
+ // Afterwards name will be: d = 1.0
15
+ rest = rest.substring(1, closer);
16
+ // mark it for the type:
17
+ optional = true;
18
+ }
19
+ // Strip the rest (either leftover of optional value or description)
20
+ const name = rest.split(' ')[0].split('=')[0].trim();
21
+ return [name, optional];
22
+ }
23
+ export {extractNameAndOptionality};
@@ -0,0 +1,13 @@
1
+ export * from './addTypeChecks.mjs';
2
+ export * from './ast2json.mjs';
3
+ export * from './ast2jsonForComparison.mjs';
4
+ export * from './code2ast2code.mjs';
5
+ export * from './expandType.mjs';
6
+ export * from './expandTypeDepFree.mjs';
7
+ export * from './extractNameAndOptionality.mjs';
8
+ export * from './parseJSDoc.mjs';
9
+ export * from './parseJSDocSetter.mjs';
10
+ export * from './parseJSDocTypedef.mjs';
11
+ export * from './simplifyType.mjs';
12
+ export * from './Stringifier.mjs';
13
+ export * from './StringifierWithTypeAssertions.mjs';
@@ -0,0 +1,69 @@
1
+ import {expandTypeDepFree} from "./expandTypeDepFree.mjs";
2
+ import {simplifyType} from "./simplifyType.mjs";
3
+ /**
4
+ * @param {string} src
5
+ * @returns {{} | undefined}
6
+ */
7
+ function parseJSDoc(src, expandType = expandTypeDepFree) {
8
+ // Parse something like: @param {Object} [kwargs={}] Optional arguments.
9
+ const regex = /@param \{(.*?)\} ([\[\]a-zA-Z0-9_$=\{\}\.'" ]+)/g;
10
+ const matches = [...src.matchAll(regex)];
11
+ /** @type {Record<string, any>} */
12
+ const params = Object.create(null);
13
+ matches.forEach(_ => {
14
+ const type = expandType(_[1].trim());
15
+ let name = _[2].trim();
16
+ let optional = false;
17
+ // Examples:
18
+ // name: [kwargs={}] The configuration parameters.
19
+ // name: [d = 1.0] Sample spacing
20
+ if (name[0] === '[') {
21
+ // Possible improvement: counting opening/closing brackets for perfect match
22
+ const closer = name.lastIndexOf(']');
23
+ // Afterwards name will be: d = 1.0
24
+ name = name.substring(1, closer);
25
+ // mark it for the type:
26
+ optional = true;
27
+ }
28
+ // Strip the rest (either leftover of optional value or description)
29
+ name = name.split(' ')[0].split('=')[0].trim();
30
+ const simplifiedType = simplifyType(type, optional);
31
+ const parts = name.split(".");
32
+ if (parts.length == 3) { // Something like: @param {number[]} settings.render.skyboxRotation - Rotation of skybox.
33
+ let parts0 = parts[0]; // settings
34
+ let parts1 = parts[1]; // render
35
+ let parts2 = parts[2]; // skyboxRotation
36
+ const toptype = params[parts0];
37
+ toptype.properties[parts1].properties = toptype.properties[parts1].properties || {};
38
+ toptype.properties[parts1].properties[parts2] = simplifiedType;
39
+ } else if (parts.length == 2) { // Something like: @param {number} description[].components
40
+ let parts0 = parts[0]; // description[]
41
+ let parts1 = parts[1]; // components
42
+ if (parts0.endsWith('[]')) {
43
+ parts0 = parts0.slice(0, -2); // description[] -> description
44
+ }
45
+ const toptype = params[parts0];
46
+ if (toptype?.type == "union") {
47
+ const typeObject = toptype.members.find(_ => _?.type == 'object');
48
+ typeObject.properties[parts1] = simplifiedType;
49
+ //typeObject.properties = simplifiedType; // todo add test case
50
+ } else if (toptype?.type == "array") {
51
+ toptype.elementType.properties[parts1] = simplifiedType;
52
+ } else if (toptype?.type == "object") {
53
+ toptype.properties = toptype.properties || {};
54
+ toptype.properties[parts1] = simplifiedType;
55
+ } else {
56
+ console.warn("parseJSDoc> skipping @param, unseen syntax detected, please check if your JSDoc is valid or open an issue about this", {
57
+ src, toptype, parts0, parts1, simplifiedType
58
+ })
59
+ }
60
+ } else {
61
+ params[name] = simplifiedType;
62
+ }
63
+ });
64
+ if (Object.keys(params).length === 0) {
65
+ return;
66
+ }
67
+ return params;
68
+ }
69
+ export {parseJSDoc};
@@ -0,0 +1,16 @@
1
+ import {expandTypeDepFree} from "./expandTypeDepFree.mjs";
2
+ import {simplifyType} from "./simplifyType.mjs";
3
+ /**
4
+ * @param {string} src - JSDoc comment of the setter.
5
+ */
6
+ function parseJSDocSetter(src, expandType = expandTypeDepFree) {
7
+ const regex = /@type \{(.*?)\}/g;
8
+ const matches = [...src.matchAll(regex)];
9
+ if (matches.length === 1) {
10
+ const match = matches[0];
11
+ const type = expandType(match[1]);
12
+ const simplifiedType = simplifyType(type, /*optional*/ false);
13
+ return simplifiedType;
14
+ }
15
+ }
16
+ export {parseJSDocSetter};
@@ -0,0 +1,69 @@
1
+ import {extractNameAndOptionality} from './extractNameAndOptionality.mjs';
2
+ import {simplifyType } from './simplifyType.mjs';
3
+ /**
4
+ * @param {string} line
5
+ * @returns {{content: string, nextIndex: number}}
6
+ */
7
+ function extractCurlyContent(line) {
8
+ const firstCurly = line.indexOf('{');
9
+ let k = firstCurly + 1;
10
+ let count = 0;
11
+ for (; k<line.length; k++) {
12
+ const c = line[k];
13
+ if (c === '{') {
14
+ count++;
15
+ } else if (c === '}') {
16
+ count--;
17
+ }
18
+ if (count === -1) {
19
+ break;
20
+ }
21
+ }
22
+ const content = line.substring(firstCurly + 1, k);
23
+ return {content, nextIndex: k + 1};
24
+ }
25
+ /**
26
+ * @param {Record<string, object>} typedefs
27
+ * @param {Console["warn"]} warn
28
+ * @param {import("@babel/types").CommentBlock | import("@babel/types").CommentLine} comment - From import("@babel/types").File["comments"]
29
+ * @param {Function} expandType
30
+ */
31
+ function parseJSDocTypedef(typedefs, warn, comment, expandType) {
32
+ const {type, value} = comment;
33
+ if (type !== 'CommentBlock') {
34
+ return;
35
+ }
36
+ const lines = value.split('\n');
37
+ let lastTypedef = undefined;
38
+ for (let line of lines) {
39
+ line = line.trim();
40
+ if (line[0] === '*') {
41
+ line = line.slice(1).trim();
42
+ }
43
+ if (line.startsWith('@typedef')) {
44
+ const {content: def, nextIndex} = extractCurlyContent(line);
45
+ let name = line.substring(nextIndex).trim();
46
+ // Drop description
47
+ name = name.split(' ')[0];
48
+ lastTypedef = expandType(def);
49
+ typedefs[name] = lastTypedef;
50
+ } else if (line.startsWith('@property')) {
51
+ // class @property
52
+ if (!lastTypedef) {
53
+ continue;
54
+ }
55
+ const {content, nextIndex} = extractCurlyContent(line);
56
+ const rest = line.substring(nextIndex);
57
+ const propType = expandType(content);
58
+ const [name, optional] = extractNameAndOptionality(rest);
59
+ // console.log({name, optional, propType});
60
+ const finalType = simplifyType(propType, optional);
61
+ if (lastTypedef?.type === 'object') {
62
+ lastTypedef.properties[name] = finalType;
63
+ } else {
64
+ warn("not an extensible type", lastTypedef);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ export {extractCurlyContent, parseJSDocTypedef};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @typedef DocType
3
+ * @property {boolean} optional
4
+ */
5
+ /**
6
+ * @param {string | DocType} type - The type.
7
+ * @param {boolean} optional - Optionality
8
+ * @returns {string | DocType}
9
+ */
10
+ function simplifyType(type, optional) {
11
+ // If it's already an object, just set optionality.
12
+ if (type instanceof Object) {
13
+ type.optional = optional;
14
+ } else if (typeof type === 'string') {
15
+ type = type.trim();
16
+ if (type != 'object' && type != 'object[]' && type != 'union' && !optional) {
17
+ // console.log("simplify", type);
18
+ return type;
19
+ }
20
+ type = {type, optional};
21
+ } else {
22
+ debugger;
23
+ console.warn("simplifyType> neither object nor string for type", type);
24
+ }
25
+ if (type.type == 'object' && type.properties && Object.keys(type.properties).length === 0) {
26
+ delete type.properties;
27
+ // console.log("delete empty", type);
28
+ }
29
+ return type;
30
+ }
31
+ export {simplifyType};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @typedef Stat
3
+ * @property {number} checked
4
+ * @property {number} unchecked
5
+ */
6
+ /**
7
+ * @param {Stat} stat - the Stat.
8
+ */
9
+ function statReset(stat) {
10
+ stat.checked = 0;
11
+ stat.unchecked = 0;
12
+ }
13
+ export {statReset};
@@ -0,0 +1,5 @@
1
+ // Instead of loading this as UMD module, we will soon integrate Babel 8, which
2
+ // finally ships as proper ESM modules. But it requires a bit more work (tm).
3
+ await import("../unpkg.com_@babel_standalone@7.22.17_babel.js");
4
+ const { parseSync } = Babel._babel;
5
+ export { parseSync };
@@ -0,0 +1,7 @@
1
+ // Test: await import("@babel/helper-plugin-utils")
2
+ /** @type {Record<string, any>} */
3
+ const exports = {};
4
+ globalThis.exports = exports;
5
+ await import("../node_modules/@babel/helper-plugin-utils/lib/index.js");
6
+ export const {declare, declarePreset} = exports;
7
+ export default exports;
@@ -0,0 +1,8 @@
1
+ // Note: this is still ugly, but Babel 8 should be "nice" ESM (when it's out)
2
+ // Test: const {parse} = await import("@babel/parser");
3
+ /** @type {Record<string, any>} */
4
+ const exports = {};
5
+ globalThis.exports = exports;
6
+ await import("../node_modules/@babel/parser/lib/index.js");
7
+ export const {parse, parseExpression, tokTypes} = exports;
8
+ export default exports;
@@ -0,0 +1,58 @@
1
+
2
+ // Test: const {babelPluginSyntaxTypeScript} = await import("@babel/plugin-syntax-typescript");
3
+ /*
4
+ const {parse} = await import("@babel/parser");
5
+ parse('type tmp = 123;', {
6
+ plugins: [babelPluginSyntaxTypeScript?]
7
+ })
8
+ */
9
+ import {declare} from '@babel/helper-plugin-utils';
10
+ /**
11
+ * @param {any[]} plugins
12
+ * @param {string} name
13
+ */
14
+ function removePlugin(plugins, name) {
15
+ const indices = [];
16
+ plugins.forEach((plugin, i) => {
17
+ const n = Array.isArray(plugin) ? plugin[0] : plugin;
18
+ if (n === name) {
19
+ indices.unshift(i);
20
+ }
21
+ });
22
+ for (const i of indices) {
23
+ plugins.splice(i, 1);
24
+ }
25
+ };
26
+ const babelPluginSyntaxTypeScript = declare((api, opts) => {
27
+ api.assertVersion(7);
28
+ const {
29
+ disallowAmbiguousJSXLike,
30
+ dts
31
+ } = opts;
32
+ {
33
+ var {
34
+ isTSX
35
+ } = opts;
36
+ }
37
+ return {
38
+ name: "syntax-typescript",
39
+ manipulateOptions(opts, parserOpts) {
40
+ {
41
+ const {
42
+ plugins
43
+ } = parserOpts;
44
+ removePlugin(plugins, "flow");
45
+ removePlugin(plugins, "jsx");
46
+ plugins.push("objectRestSpread", "classProperties");
47
+ if (isTSX) {
48
+ plugins.push("jsx");
49
+ }
50
+ }
51
+ parserOpts.plugins.push(["typescript", {
52
+ disallowAmbiguousJSXLike,
53
+ dts
54
+ }]);
55
+ }
56
+ };
57
+ });
58
+ export {babelPluginSyntaxTypeScript};
@@ -0,0 +1,38 @@
1
+ function importFile(content) {
2
+ return "data:text/javascript;base64," + btoa(content);
3
+ }
4
+ const imports = {
5
+ //"@babel/core": "./babel-core.mjs",
6
+ "@babel/parser": "./babel-parser.mjs",
7
+ //"@babel/helper-plugin-utils": "./babel-helper-plugin-utils.mjs",
8
+ //"@babel/plugin-syntax-typescript": "./babel-plugin-syntax-typescript.mjs",
9
+ "fs": importFile("export default {};"),
10
+ "typescript": importFile("export default ts;"), // UMD import
11
+ /*
12
+ "path": importFile("export default {};"),
13
+ "stream/web": importFile("export default {};"),
14
+ "sharp": importFile("export default {};"),
15
+ "onnxruntime-node": importFile("export default {};"),
16
+ "onnxruntime-web": importFile(`
17
+ //await import("https://cdnjs.cloudflare.com/ajax/libs/onnxruntime-web/1.15.0/ort.es6.min.js");
18
+ await import("https://cdnjs.cloudflare.com/ajax/libs/onnxruntime-web/1.14.0/ort.es6.min.js");
19
+ //http://127.0.0.1/transformer/onnxruntime/js/common/dist/
20
+ //await import("http://127.0.0.1/transformer/onnxruntime/js/common/dist/ort-common.js");
21
+ //await import("http://127.0.0.1/transformer/onnxruntime/js/web/dist/ort-webgl.js");
22
+ //await import("https://cdnjs.cloudflare.com/ajax/libs/onnxruntime-web/1.14.0/ort.es6.min.js");
23
+ let ONNX = globalThis.ort;
24
+ export default ONNX;
25
+ export {
26
+ ONNX
27
+ };
28
+ `),
29
+ */
30
+ };
31
+ const importmap = document.createElement("script");
32
+ importmap.type = "importmap";
33
+ importmap.textContent = JSON.stringify({imports});
34
+ const parent = document.body || document.head;
35
+ if (!parent) {
36
+ throw "neither <body> nor <head> available to append importmap";
37
+ }
38
+ parent.append(importmap);