socket-function 0.8.36 → 0.8.38

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.
@@ -0,0 +1 @@
1
+ export function parse(text: string): unknown;
@@ -0,0 +1,248 @@
1
+ // JSON Grammar
2
+ // ============
3
+ //
4
+ // Based on the grammar from RFC 7159 [1].
5
+ //
6
+ // Note that JSON is also specified in ECMA-262 [2], ECMA-404 [3], and on the
7
+ // JSON website [4] (somewhat informally). The RFC seems the most authoritative
8
+ // source, which is confirmed e.g. by [5].
9
+ //
10
+ // [1] http://tools.ietf.org/html/rfc7159
11
+ // [2] http://www.ecma-international.org/publications/standards/Ecma-262.htm
12
+ // [3] http://www.ecma-international.org/publications/standards/Ecma-404.htm
13
+ // [4] http://json.org/
14
+ // [5] https://www.tbray.org/ongoing/When/201x/2014/03/05/RFC7159-JSON
15
+
16
+ // MODIFIED to support more javascript syntax, copying syntax from: https://github.com/pegjs/pegjs/blob/master/examples/javascript.pegjs
17
+
18
+ // ----- 2. JSON Grammar -----
19
+
20
+ JSON_text
21
+ = ws value:value ws { return value; }
22
+
23
+ begin_array = ws "[" ws
24
+ begin_object = ws "{" ws
25
+ end_array = ws "]" ws
26
+ end_object = ws "}" ws
27
+ name_separator = ws ":" ws
28
+ value_separator = ws "," ws
29
+
30
+ ws "whitespace"
31
+ = wsBase*
32
+
33
+ wsBase
34
+ = [ \t\n\r]
35
+ / Comment
36
+
37
+ Comment "comment"
38
+ = MultiLineComment
39
+ / SingleLineComment
40
+
41
+ MultiLineComment
42
+ = "/*" (!"*/" .)* "*/"
43
+
44
+ MultiLineCommentNoLineTerminator
45
+ = "/*" (!("*/" / LineTerminator) .)* "*/"
46
+
47
+ SingleLineComment
48
+ = "//" (!LineTerminator .)*
49
+
50
+ LineTerminator
51
+ = [\n\r\u2028\u2029]
52
+
53
+ // ----- 3. Values -----
54
+
55
+ value
56
+ = false
57
+ / null
58
+ / true
59
+ / object
60
+ / array
61
+ / number
62
+ / string
63
+
64
+ false = "false" { return false; }
65
+ null = "null" { return null; }
66
+ true = "true" { return true; }
67
+
68
+ // ----- 4. Objects -----
69
+
70
+ object
71
+ = begin_object
72
+ members:(
73
+ head:member
74
+ tail:(value_separator? m:member { return m; })*
75
+ {
76
+ var result = {};
77
+
78
+ [head].concat(tail).forEach(function(element) {
79
+ result[element.name] = element.value;
80
+ });
81
+
82
+ return result;
83
+ }
84
+ )?
85
+ end_object
86
+ { return members !== null ? members: {}; }
87
+
88
+ member
89
+ = name:member_name name_separator value:value value_separator? {
90
+ return { name: name, value: value };
91
+ }
92
+
93
+ member_name "member_name"
94
+ = string
95
+ / Identifier
96
+
97
+ Identifier
98
+ = name:IdentifierName { return name.name; }
99
+
100
+ IdentifierName "identifier"
101
+ = head:IdentifierStart tail:IdentifierPart* {
102
+ return {
103
+ type: "Identifier",
104
+ name: head + tail.join("")
105
+ };
106
+ }
107
+
108
+ IdentifierStart
109
+ = UnicodeLetter
110
+ / "$"
111
+ / "_"
112
+
113
+ UnicodeLetter
114
+ = Lu
115
+ / Ll
116
+ / Lt
117
+ / Lm
118
+ / Lo
119
+ / Nl
120
+
121
+ UnicodeDigit
122
+ = Nd
123
+
124
+ UnicodeConnectorPunctuation
125
+ = Pc
126
+
127
+ // Letter, Lowercase
128
+ Ll = [\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0560-\u0588\u10D0-\u10FA\u10FD-\u10FF\u13F8-\u13FD\u1C80-\u1C88\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AF\uA7B5\uA7B7\uA7B9\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A]
129
+
130
+ // Letter, Modifier
131
+ Lm = [\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F]
132
+
133
+ // Letter, Other
134
+ Lo = [\u00AA\u00BA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05EF-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u09FC\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u1100-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD-\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]
135
+
136
+ // Letter, Titlecase
137
+ Lt = [\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC]
138
+
139
+ // Letter, Uppercase
140
+ Lu = [\u0041-\u005A\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1C90-\u1CBA\u1CBD-\u1CBF\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AE\uA7B0-\uA7B4\uA7B6\uA7B8\uFF21-\uFF3A]
141
+
142
+ // Mark, Spacing Combining
143
+ Mc = [\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0BBE-\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82-\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2-\u0DF3\u0F3E-\u0F3F\u0F7F\u102B-\u102C\u1031\u1038\u103B-\u103C\u1056-\u1057\u1062-\u1064\u1067-\u106D\u1083-\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF2-\u1CF3\u1CF7\u302E-\u302F\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC]
144
+
145
+ // Mark, Nonspacing
146
+ Mn = [\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2-\u09E3\u09FE\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62-\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC-\u0CCD\u0CE2-\u0CE3\u0D00-\u0D01\u0D3B-\u0D3C\u0D41-\u0D44\u0D4D\u0D62-\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885-\u1886\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099-\u309A\uA66F\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1\uA802\uA806\uA80B\uA825-\uA826\uA8C4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]
147
+
148
+ // Number, Decimal Digit
149
+ Nd = [\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]
150
+
151
+ // Number, Letter
152
+ Nl = [\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF]
153
+
154
+ // Punctuation, Connector
155
+ Pc = [\u005F\u203F-\u2040\u2054\uFE33-\uFE34\uFE4D-\uFE4F\uFF3F]
156
+
157
+ // Separator, Space
158
+ Zs = [\u0020\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]
159
+
160
+ IdentifierPart
161
+ = IdentifierStart
162
+ / UnicodeDigit
163
+ / UnicodeConnectorPunctuation
164
+ / "\u200C"
165
+ / "\u200D"
166
+
167
+ // ----- 5. Arrays -----
168
+
169
+ array
170
+ = begin_array
171
+ values:(
172
+ head:value
173
+ tail:(value_separator v:value { return v; })*
174
+ { return [head].concat(tail); }
175
+ )?
176
+ value_separator?
177
+ end_array
178
+ { return values !== null ? values : []; }
179
+
180
+ // ----- 6. Numbers -----
181
+
182
+ number "number"
183
+ = minus? int frac? exp? { return parseFloat(text()); }
184
+
185
+ decimal_point
186
+ = "."
187
+
188
+ digit1_9
189
+ = [1-9]
190
+
191
+ e
192
+ = [eE]
193
+
194
+ exp
195
+ = e (minus / plus)? DIGIT+
196
+
197
+ frac
198
+ = decimal_point DIGIT+
199
+
200
+ int
201
+ = zero / (digit1_9 DIGIT*)
202
+
203
+ minus
204
+ = "-"
205
+
206
+ plus
207
+ = "+"
208
+
209
+ zero
210
+ = "0"
211
+
212
+ // ----- 7. Strings -----
213
+
214
+ string "string"
215
+ = quotation_mark chars:char* quotation_mark { return chars.join(""); }
216
+
217
+ char
218
+ = unescaped
219
+ / escape
220
+ sequence:(
221
+ '"'
222
+ / "\\"
223
+ / "/"
224
+ / "b" { return "\b"; }
225
+ / "f" { return "\f"; }
226
+ / "n" { return "\n"; }
227
+ / "r" { return "\r"; }
228
+ / "t" { return "\t"; }
229
+ / "u" digits:$(HEXDIG HEXDIG HEXDIG HEXDIG) {
230
+ return String.fromCharCode(parseInt(digits, 16));
231
+ }
232
+ )
233
+ { return sequence; }
234
+
235
+ escape
236
+ = "\\"
237
+
238
+ quotation_mark
239
+ = '"'
240
+
241
+ unescaped
242
+ = [^\0-\x1F\x22\x5C]
243
+
244
+ // ----- Core ABNF Rules -----
245
+
246
+ // See RFC 4234, Appendix B (http://tools.ietf.org/html/rfc4234).
247
+ DIGIT = [0-9]
248
+ HEXDIG = [0-9a-f]i
@@ -0,0 +1,376 @@
1
+
2
+ import { enableMeasurements, measureBlock, measureCode, measureCodeSync, measureFnc } from "../profiling/measure";
3
+ // enableMeasurements();
4
+
5
+ import debugbreak from "debugbreak";
6
+ import fs from "fs";
7
+
8
+ import parser from "./JSONLACKS.generated.js";
9
+ import { recursiveFreeze } from "../misc";
10
+ import { canHaveChildren } from "../types";
11
+
12
+ // Supports json and also:
13
+ // - Non quoted field names "{ x: 1 }"?
14
+ // - Trailing commas
15
+ // NOTE: Comma only syntax is not supported, ex, "[,,]", which is an array of length 2 in javascript
16
+ // - Comments on input, but not on output
17
+ // - References
18
+ // - Buffers (just Buffers, not typed arrays)
19
+ // The stringify function always creates valid json, as the syntax for references and buffers
20
+ // will just be special property names and values.
21
+ // NOTE: We don't support Date serialization. Never store Dates, store "number".
22
+
23
+ export interface JSONLACKS_ParseConfig {
24
+ // Defaults to true. Enables parsing of:
25
+ // - Trailing commas
26
+ // - Non-quoted field names (ex, "{ x: 1 }")
27
+ // - Comments (strips them, but doesn't throw)
28
+ extended?: boolean;
29
+ }
30
+ export interface JSONLACKS_StringifyConfig {
31
+ // If specified, we are allowed to mutate the provided object. Speeds up serialization.
32
+ allowObjectMutation?: boolean;
33
+ }
34
+
35
+ export class JSONLACKS {
36
+ public static readonly LACKS_KEY = "__JSONLACKS__98cfb4a05fa34d828661cae15b8779ce__";
37
+
38
+ /** If set to true parses non-quoted field names, comments, trailing commas, etc */
39
+ public static EXTENDED_PARSER = true;
40
+ public static IGNORE_MISSING_REFERENCES = false;
41
+
42
+ @measureFnc
43
+ public static stringify(obj: unknown, config?: JSONLACKS_StringifyConfig): string {
44
+ let serialized = JSONLACKS.escapeSpecialObjects(obj, config);
45
+ return measureBlock(function JSONstringify() { return JSON.stringify(serialized); });
46
+ }
47
+ /** Is useful when serializing an array to a file with one object per line */
48
+ @measureFnc
49
+ public static stringifyFile(obj: unknown[], config?: JSONLACKS_StringifyConfig): string {
50
+ let serialized = JSONLACKS.escapeSpecialObjects(obj, config) as unknown[];
51
+ return measureBlock(function JSONstringifyAndJoin() { return serialized.map(x => JSON.stringify(x)).join("\n"); });
52
+ }
53
+ // TIMING: Seems to be about 40X slower than JSON.parse unless extended is set to false,
54
+ // then it is about 2X slower (although it depends on the size and complexity of the objects!)
55
+ @measureFnc
56
+ public static parse<T>(text: string, config?: JSONLACKS_ParseConfig): T {
57
+ let obj: unknown;
58
+
59
+ let extendedParsing = config?.extended ?? JSONLACKS.EXTENDED_PARSER;
60
+
61
+ if (extendedParsing) {
62
+ obj = measureBlock(function JSONextendedParse() { return parser.parse(text); });
63
+ } else {
64
+ obj = measureBlock(function JSONparse() { return JSON.parse(text); });
65
+ }
66
+
67
+ return JSONLACKS.hydrateSpecialObjects(obj) as T;
68
+ }
69
+ @measureFnc
70
+ public static parseLines<T>(text: string, config?: JSONLACKS_ParseConfig): T {
71
+ let lines = text
72
+ .replaceAll("\r", "")
73
+ .split("\n")
74
+ .filter(x => x && !x.startsWith("//"))
75
+ ;
76
+ let linesJSON = "[";
77
+ for (let i = 0; i < lines.length; i++) {
78
+ if (i !== 0) linesJSON += ",";
79
+ linesJSON += lines[i];
80
+ }
81
+ linesJSON += "]";
82
+ return JSONLACKS.parse(linesJSON, config);
83
+ }
84
+
85
+ @measureFnc
86
+ private static escapeSpecialObjects(obj: unknown, config?: JSONLACKS_StringifyConfig): unknown {
87
+ // I think iterating twice for references is the fastest way to do it?
88
+ let objects = new Set<unknown>();
89
+ // NOTE: Use unique values for references, to allow concatenating files without having to
90
+ // deal with escaping references.
91
+ let refPrefix = Date.now() + Math.random() + "";
92
+ let nextRefId = 0;
93
+ function getNextRefKey() {
94
+ return refPrefix + "_" + nextRefId++;
95
+ }
96
+ let refObjects = new Map<unknown, string>();
97
+ findReferences(obj);
98
+ function findReferences(obj: unknown) {
99
+ if (!canHaveChildren(obj)) return;
100
+ if (refObjects.has(obj)) return;
101
+ if (objects.has(obj)) {
102
+ let refKey = getNextRefKey();
103
+ refObjects.set(obj, refKey);
104
+ return;
105
+ }
106
+ objects.add(obj);
107
+ for (let key in obj) {
108
+ findReferences(obj[key]);
109
+ }
110
+ }
111
+
112
+ let refsSeen = new Set<unknown>();
113
+ return iterate(obj);
114
+ function iterate(obj: unknown, refHandled?: boolean): unknown {
115
+ if (!canHaveChildren(obj)) return obj;
116
+ if (!refHandled) {
117
+ let refKey = refObjects.get(obj);
118
+ if (refKey) {
119
+ if (refsSeen.has(obj)) {
120
+ return {
121
+ [JSONLACKS.LACKS_KEY]: "ref",
122
+ id: refKey,
123
+ };
124
+ }
125
+ refsSeen.add(obj);
126
+ return {
127
+ [JSONLACKS.LACKS_KEY]: "define",
128
+ id: refKey,
129
+ value: iterate(obj, true),
130
+ };
131
+ }
132
+ }
133
+
134
+ if (JSONLACKS.LACKS_KEY in obj) {
135
+ let restOfObj = { ...obj };
136
+ let escapedValue = restOfObj[JSONLACKS.LACKS_KEY];
137
+ delete restOfObj[JSONLACKS.LACKS_KEY];
138
+ return {
139
+ [JSONLACKS.LACKS_KEY]: "removedSpecialKey",
140
+ escapedValue: iterate(escapedValue),
141
+ restOfObj: iterate(restOfObj),
142
+ };
143
+ }
144
+
145
+ if (obj instanceof Buffer) {
146
+ return {
147
+ [JSONLACKS.LACKS_KEY]: "Buffer",
148
+ data: obj.toString("base64"),
149
+ };
150
+ }
151
+
152
+ let cloned = config?.allowObjectMutation;
153
+ function cloneObj() {
154
+ if (cloned) return;
155
+ cloned = true;
156
+ if (Array.isArray(obj)) {
157
+ obj = [...obj];
158
+ } else {
159
+ obj = { ...obj as any };
160
+ }
161
+ };
162
+ for (let key in obj) {
163
+ let originalValue = obj[key];
164
+ let value = iterate(originalValue);
165
+ if (value !== originalValue) {
166
+ cloneObj();
167
+ obj[key] = value;
168
+ }
169
+ }
170
+ return obj;
171
+ }
172
+ }
173
+
174
+ @measureFnc
175
+ private static hydrateSpecialObjects(obj: unknown): unknown {
176
+ let references = new Map<string, unknown>();
177
+ let visited = new Set<unknown>();
178
+ return iterate(obj);
179
+ function iterate(obj: unknown) {
180
+ if (!canHaveChildren(obj)) return obj;
181
+ if (visited.has(obj)) return obj;
182
+ visited.add(obj);
183
+ let type = obj[JSONLACKS.LACKS_KEY];
184
+ if (!type) {
185
+ for (let key in obj) {
186
+ let originalValue = obj[key];
187
+ let value = iterate(originalValue);
188
+ if (value !== originalValue) {
189
+ obj[key] = value;
190
+ }
191
+ }
192
+ return obj;
193
+ }
194
+ if (type === "removedSpecialKey") {
195
+ let restOfObj = iterate(obj.restOfObj) as any;
196
+ let escapedValue = iterate(obj.escapedValue) as any;
197
+ return { ...restOfObj, [JSONLACKS.LACKS_KEY]: escapedValue };
198
+ }
199
+ if (type === "Buffer") {
200
+ return Buffer.from(obj.data as string, "base64");
201
+ }
202
+ if (type === "define") {
203
+ references.set(obj.id as string, iterate(obj.value));
204
+ return obj.value;
205
+ }
206
+ if (type === "ref") {
207
+ let id = obj.id as string;
208
+ if (!JSONLACKS.IGNORE_MISSING_REFERENCES && !references.has(id)) {
209
+ // TODO: Add a mode where we can ignore
210
+ throw new Error(`Reference to undefined id "${id}"`);
211
+ }
212
+ return references.get(id);
213
+ }
214
+ throw new Error(`Unknown lacks type "${type}"`);
215
+ }
216
+ }
217
+ }
218
+
219
+ async function benchmark() {
220
+ const loops = 1000 * 100;
221
+ let inputs: string[] = [];
222
+ for (let i = 0; i < loops; i++) {
223
+ inputs.push(JSON.stringify({
224
+ i,
225
+ hello_there: i,
226
+ example: 5,
227
+ list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
228
+ }) + " ");
229
+ }
230
+ JSON.parse(inputs[0]);
231
+ parser.parse(inputs[0]);
232
+
233
+ measureCodeSync(function measure() {
234
+ measureBlock(function JSON_PARSE() {
235
+ for (let i = 0; i < loops; i++) {
236
+ JSON.parse(inputs[i]);
237
+ }
238
+ });
239
+ measureBlock(function JSON_PARSE_FREEZE() {
240
+ for (let i = 0; i < loops; i++) {
241
+ let obj = JSON.parse(inputs[i]);
242
+ recursiveFreeze(obj);
243
+ }
244
+ });
245
+
246
+ measureBlock(function EXTENDED_PARSE() {
247
+ for (let i = 0; i < loops; i++) {
248
+ parser.parse(inputs[i]);
249
+ }
250
+ });
251
+
252
+ measureBlock(function JSONLACKS_PARSE() {
253
+ for (let i = 0; i < loops; i++) {
254
+ JSONLACKS.parse(inputs[i]);
255
+ }
256
+ });
257
+ measureBlock(function JSONLACKS_PARSE_SIMPLE() {
258
+ for (let i = 0; i < loops; i++) {
259
+ JSONLACKS.parse(inputs[i], { extended: false });
260
+ }
261
+ });
262
+
263
+ }, {
264
+ thresholdInTable: 0
265
+ });
266
+
267
+ }
268
+ //benchmark().catch(console.error).finally(() => process.exit());
269
+
270
+
271
+ async function testJSONLACKS() {
272
+ {
273
+ let obj = {};
274
+ let str = JSONLACKS.stringify({
275
+ a: obj,
276
+ b: obj,
277
+ });
278
+ let parsed = JSONLACKS.parse(str) as any;
279
+ if (parsed.a !== parsed.b) {
280
+ throw new Error("Failed to maintain references");
281
+ }
282
+ if (typeof parsed.a !== "object") {
283
+ throw new Error("Object become corrupted");
284
+ }
285
+ }
286
+
287
+ // Test LACKS_KEY is escaped correctly
288
+ {
289
+ let obj = { [JSONLACKS.LACKS_KEY]: "hello" };
290
+ let str = JSONLACKS.stringify(obj);
291
+ let parsed = JSONLACKS.parse(str) as any;
292
+ if (JSON.stringify(obj) !== JSON.stringify(parsed)) {
293
+ throw new Error("Failed to escape LACKS_KEY");
294
+ }
295
+ }
296
+ // Test buffers are preserved
297
+ {
298
+ let obj = { a: Buffer.from("hello") };
299
+ let str = JSONLACKS.stringify(obj);
300
+ let parsed = JSONLACKS.parse(str) as any;
301
+ if (obj.a.toString() !== parsed.a.toString()) {
302
+ throw new Error(`Failed to preserve buffers`);
303
+ }
304
+ }
305
+
306
+ // Test references 2
307
+ {
308
+ let base = {};
309
+ let arr = [base, base];
310
+ let obj = { x: arr, y: arr };
311
+ let result = JSONLACKS.parse(JSONLACKS.stringify(obj), { extended: false }) as typeof obj;
312
+ if (JSON.stringify(result) !== JSON.stringify(obj)) {
313
+ throw new Error(`Corrupted values, expected ${JSON.stringify(obj)}, got ${JSON.stringify(result)}`);
314
+ }
315
+ if (result.x !== result.y) {
316
+ throw new Error(`Failed to maintain references`);
317
+ }
318
+ if (result.x[0] !== result.x[1]) {
319
+ throw new Error(`Failed to maintain references`);
320
+ }
321
+ }
322
+ }
323
+ //testJSONLACKS().catch(console.error).finally(() => process.exit());
324
+
325
+ async function generateAndVerifyParser() {
326
+ const pegjs = await import("pegjs");
327
+
328
+ var grammar = fs.readFileSync(__dirname + "/JSONLACKS.pegjs", "utf8");
329
+ var parserSource = pegjs.generate(grammar, { output: "source", format: "commonjs" });
330
+ fs.writeFileSync(__dirname + "/JSONLACKS.generated.js", parserSource);
331
+
332
+ var module = { exports: {} };
333
+ eval(parserSource);
334
+ const parser = module.exports as any;
335
+ function verify(text: string) {
336
+ var parsed = parser.parse(text);
337
+ var result = JSON.stringify(parsed);
338
+ let realResult = JSON.stringify(eval("(" + text + ")"));
339
+ if (result !== realResult) {
340
+ throw new Error(`Failed to parse: ${text} should be ${realResult}, was ${result}`);
341
+ }
342
+ }
343
+
344
+ verify(`
345
+ {
346
+ "hello_there": 1,
347
+ }
348
+ `);
349
+ verify(`
350
+ {
351
+ hello_there: 1,
352
+ }
353
+ `);
354
+ verify(`
355
+ {
356
+ hello_there: 1,
357
+ more: 1,
358
+ }
359
+ `);
360
+ verify(`{ list: [1,], }`);
361
+ verify(`{ list: [1,], list2: [1,], }`);
362
+
363
+ verify(`{ /* test */ list: [1,], list2: [1,], }`);
364
+ verify(`{ /* test */ /* test 2 */ list: [1,], list2: [1,], }`);
365
+ verify(`
366
+ {
367
+ /* test */
368
+ /* test 2 */
369
+ list: [1,],
370
+ // Single line comment
371
+ list2: [1,],
372
+ // list3: [3],
373
+ }
374
+ `);
375
+ }
376
+ //generateAndVerifyParser().catch(console.error).finally(() => process.exit());