@lvce-editor/shared-process 0.16.1 → 0.16.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.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022-present, Lvce Editor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ {
2
+ "comments": {
3
+ "blockComment": ["/*", "*/"]
4
+ },
5
+ "brackets": [
6
+ ["{", "}"],
7
+ ["[", "]"],
8
+ ["(", ")"]
9
+ ],
10
+ "autoClosingPairs": [
11
+ { "open": "{", "close": "}", "notIn": ["string", "comment"] },
12
+ { "open": "[", "close": "]", "notIn": ["string", "comment"] },
13
+ { "open": "(", "close": ")", "notIn": ["string", "comment"] },
14
+ { "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
15
+ { "open": "'", "close": "'", "notIn": ["string", "comment"] }
16
+ ]
17
+ }
@@ -2,27 +2,567 @@
2
2
  * @enum number
3
3
  */
4
4
  export const TokenType = {
5
- Text: 1,
5
+ CssSelector: 1,
6
+ Whitespace: 2,
7
+ Punctuation: 3,
8
+ CssPropertyName: 4,
9
+ CssPropertyValue: 5,
10
+ CurlyOpen: 6,
11
+ CurlyClose: 7,
12
+ PropertyColon: 8,
13
+ CssPropertySemicolon: 9,
14
+ Variable: 10,
15
+ None: 57,
16
+ Unknown: 881,
17
+ CssPropertyColon: 882,
18
+ Numeric: 883,
19
+ NewLine: 884,
20
+ Comment: 885,
21
+ Query: 886,
22
+ Text: 887,
23
+ CssSelectorId: 889,
24
+ FuntionName: 890,
25
+ String: 891,
26
+ KeywordImport: 892,
27
+ CssSelectorClass: 893,
6
28
  }
7
29
 
8
30
  export const TokenMap = {
31
+ [TokenType.CssSelector]: 'CssSelector',
32
+ [TokenType.Whitespace]: 'Whitespace',
33
+ [TokenType.Punctuation]: 'Punctuation',
34
+ [TokenType.CssPropertyName]: 'CssPropertyName',
35
+ [TokenType.CssPropertyValue]: 'CssPropertyValue',
36
+ [TokenType.CurlyOpen]: 'Punctuation',
37
+ [TokenType.CurlyClose]: 'Punctuation',
38
+ [TokenType.PropertyColon]: 'Punctuation',
39
+ [TokenType.CssPropertySemicolon]: 'Punctuation',
40
+ [TokenType.Variable]: 'VariableName',
41
+ [TokenType.None]: 'None',
42
+ [TokenType.CssPropertyValue]: 'CssPropertyValue',
43
+ [TokenType.Unknown]: 'Unknown',
44
+ [TokenType.CssPropertyColon]: 'Punctuation',
45
+ [TokenType.Numeric]: 'Numeric',
46
+ [TokenType.NewLine]: 'NewLine',
47
+ [TokenType.Comment]: 'Comment',
48
+ [TokenType.Query]: 'CssAtRule',
9
49
  [TokenType.Text]: 'Text',
50
+ [TokenType.CssSelectorId]: 'CssSelectorId',
51
+ [TokenType.FuntionName]: 'Function',
52
+ [TokenType.String]: 'String',
53
+ [TokenType.KeywordImport]: 'KeywordImport',
54
+ [TokenType.CssSelectorClass]: 'CssSelectorClass',
55
+ }
56
+
57
+ /**
58
+ * @enum number
59
+ */
60
+ export const State = {
61
+ TopLevelContent: 1,
62
+ AfterSelector: 2,
63
+ InsideSelector: 3,
64
+ AfterPropertyName: 4,
65
+ AfterPropertyNameAfterColon: 5,
66
+ InsideBlockComment: 7,
67
+ InsidePseudoSelector: 8,
68
+ InsideAttributeSelector: 9,
69
+ AfterQuery: 10,
70
+ InsideRound: 11,
71
+ AfterQueryWithRules: 12,
72
+ InsideRule: 13,
73
+ AfterFunctionName: 14,
74
+ InsideDoubleQuoteString: 15,
75
+ InsideSingleQuoteString: 16,
76
+ AfterFunctionNameInsideArguments: 17,
77
+ AfterKeywordImport: 18,
10
78
  }
11
79
 
12
80
  export const initialLineState = {
13
- state: 1,
81
+ state: State.TopLevelContent,
14
82
  tokens: [],
83
+ stack: [],
15
84
  }
16
85
 
17
86
  export const hasArrayReturn = true
18
87
 
88
+ const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>\+\~\_%\\]+/
89
+ const RE_SELECTOR_ID = /^#[\w\-\_]+/
90
+ const RE_SELECTOR_CLASS = /^\.[\w\-\_]+/
91
+ const RE_WHITESPACE = /^\s+/
92
+ const RE_CURLY_OPEN = /^\{/
93
+ const RE_CURLY_CLOSE = /^\}/
94
+ const RE_PROPERTY_NAME = /^[a-zA-Z\-\w]+/
95
+ const RE_COLON = /^:/
96
+ const RE_PROPERTY_VALUE = /^[^;\}]+/
97
+ const RE_PROPERTY_VALUE_SHORT = /^[^;\}\s\)]+/
98
+ const RE_PROPERTY_VALUE_INSIDE_FUNCTION = /^[^\}\s\)]+/
99
+ const RE_SEMICOLON = /^;/
100
+ const RE_COMMA = /^,/
101
+ const RE_ANYTHING = /^.+/s
102
+ const RE_NUMERIC = /^\-?(([0-9]+\.?[0-9]*)|(\.[0-9]+))/
103
+ const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
104
+ const RE_BLOCK_COMMENT_START = /^\/\*/
105
+ const RE_BLOCK_COMMENT_END = /^\*\//
106
+ const RE_BLOCK_COMMENT_CONTENT = /^.+?(?=\*\/|$)/s
107
+ const RE_ROUND_OPEN = /^\(/
108
+ const RE_ROUND_CLOSE = /^\)/
109
+ const RE_PSEUDO_SELECTOR_CONTENT = /^[^\)]+/
110
+ const RE_SQUARE_OPEN = /^\[/
111
+ const RE_SQUARE_CLOSE = /^\]/
112
+ const RE_ATTRIBUTE_SELECTOR_CONTENT = /^[^\]]+/
113
+ const RE_QUERY = /^@[a-z\-]+/
114
+ const RE_STAR = /^\*/
115
+ const RE_QUERY_NAME = /^[a-zA-Z\w\-\d\_]+/
116
+ const RE_QUERY_CONTENT = /^[^\)]+/
117
+ const RE_COMBINATOR = /^[\+\>\~]/
118
+ const RE_FUNCTION = /^[a-zA-Z][a-zA-Z\-]+(?=\()/
119
+ const RE_VARIABLE_NAME = /^\-\-[a-zA-Z\w\-\_]+/
120
+ const RE_PERCENT = /^\%/
121
+ const RE_OPERATOR = /^[\-\/\*\+]/
122
+ const RE_DOUBLE_QUOTE = /^"/
123
+ const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
124
+ const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
125
+ const RE_SINGLE_QUOTE = /^'/
126
+ const RE_ANYTHING_BUT_CURLY = /^[^\{\}]+/s
127
+ const RE_LINE_COMMENT = /\/\/.*/
128
+
19
129
  /**
20
130
  * @param {string} line
131
+ * @param {any} lineState
21
132
  */
22
- export const tokenizeLine = (line) => {
23
- const tokens = [TokenType.Text, line.length]
133
+ export const tokenizeLine = (line, lineState) => {
134
+ let next = null
135
+ let index = 0
136
+ let tokens = []
137
+ let token = TokenType.None
138
+ let state = lineState.state
139
+ const stack = lineState.stack
140
+ while (index < line.length) {
141
+ const part = line.slice(index)
142
+ switch (state) {
143
+ case State.TopLevelContent:
144
+ if ((next = part.match(RE_SELECTOR_CLASS))) {
145
+ token = TokenType.CssSelectorClass
146
+ state = State.AfterSelector
147
+ } else if ((next = part.match(RE_SELECTOR))) {
148
+ token = TokenType.CssSelector
149
+ state = State.AfterSelector
150
+ } else if ((next = part.match(RE_SELECTOR_ID))) {
151
+ token = TokenType.CssSelectorId
152
+ state = State.AfterSelector
153
+ } else if ((next = part.match(RE_WHITESPACE))) {
154
+ token = TokenType.Whitespace
155
+ state = State.TopLevelContent
156
+ } else if ((next = part.match(RE_CURLY_OPEN))) {
157
+ token = TokenType.CurlyOpen
158
+ state = State.InsideSelector
159
+ } else if ((next = part.match(RE_BLOCK_COMMENT_START))) {
160
+ token = TokenType.Comment
161
+ state = State.InsideBlockComment
162
+ } else if ((next = part.match(RE_LINE_COMMENT))) {
163
+ token = TokenType.Comment
164
+ state = State.TopLevelContent
165
+ } else if ((next = part.match(RE_SQUARE_OPEN))) {
166
+ token = TokenType.Punctuation
167
+ state = State.InsideAttributeSelector
168
+ } else if ((next = part.match(RE_QUERY))) {
169
+ switch (next[0]) {
170
+ case '@font-face':
171
+ case '@-ms-viewport':
172
+ case '@-o-viewport':
173
+ case '@viewport':
174
+ token = TokenType.Query
175
+ state = State.AfterQueryWithRules
176
+ break
177
+ case '@import':
178
+ token = TokenType.KeywordImport
179
+ state = State.AfterKeywordImport
180
+ break
181
+ case '@keyframes':
182
+ default:
183
+ token = TokenType.Query
184
+ state = State.AfterQuery
185
+ break
186
+ }
187
+ } else if ((next = part.match(RE_STAR))) {
188
+ token = TokenType.CssSelector
189
+ state = State.AfterSelector
190
+ } else if ((next = part.match(RE_CURLY_CLOSE))) {
191
+ token = TokenType.Punctuation
192
+ state = State.TopLevelContent
193
+ } else if ((next = part.match(RE_SEMICOLON))) {
194
+ token = TokenType.Punctuation
195
+ state = State.TopLevelContent
196
+ } else if ((next = part.match(RE_ANYTHING))) {
197
+ token = TokenType.Unknown
198
+ state = State.TopLevelContent
199
+ } else {
200
+ part //?
201
+ throw new Error('no')
202
+ }
203
+ break
204
+ case State.AfterSelector:
205
+ if ((next = part.match(RE_WHITESPACE))) {
206
+ token = TokenType.Whitespace
207
+ state = State.AfterSelector
208
+ } else if ((next = part.match(RE_CURLY_OPEN))) {
209
+ token = TokenType.CurlyOpen
210
+ state = State.InsideSelector
211
+ } else if ((next = part.match(RE_SELECTOR_CLASS))) {
212
+ token = TokenType.CssSelectorClass
213
+ state = State.AfterSelector
214
+ } else if ((next = part.match(RE_SELECTOR))) {
215
+ token = TokenType.CssSelector
216
+ state = State.AfterSelector
217
+ } else if ((next = part.match(RE_SELECTOR_ID))) {
218
+ token = TokenType.CssSelectorId
219
+ state = State.AfterSelector
220
+ } else if ((next = part.match(RE_COMMA))) {
221
+ token = TokenType.Punctuation
222
+ state = State.AfterSelector
223
+ } else if ((next = part.match(RE_ROUND_OPEN))) {
224
+ token = TokenType.Punctuation
225
+ state = State.InsidePseudoSelector
226
+ } else if ((next = part.match(RE_SQUARE_OPEN))) {
227
+ token = TokenType.Punctuation
228
+ state = State.InsideAttributeSelector
229
+ } else if ((next = part.match(RE_STAR))) {
230
+ token = TokenType.CssSelector
231
+ state = State.AfterSelector
232
+ } else if ((next = part.match(RE_ANYTHING_BUT_CURLY))) {
233
+ token = TokenType.Unknown
234
+ state = State.AfterSelector
235
+ } else if ((next = part.match(RE_ANYTHING))) {
236
+ token = TokenType.Unknown
237
+ state = State.TopLevelContent
238
+ } else {
239
+ part //?
240
+ throw new Error('no')
241
+ }
242
+ break
243
+ case State.AfterQuery:
244
+ if ((next = part.match(RE_WHITESPACE))) {
245
+ token = TokenType.Whitespace
246
+ state = State.AfterQuery
247
+ } else if ((next = part.match(RE_QUERY_NAME))) {
248
+ token = TokenType.Text
249
+ state = State.AfterQuery
250
+ } else if ((next = part.match(RE_CURLY_OPEN))) {
251
+ token = TokenType.Punctuation
252
+ state = State.TopLevelContent
253
+ // stack.push(State.que )
254
+ } else if ((next = part.match(RE_ROUND_OPEN))) {
255
+ token = TokenType.Punctuation
256
+ state = State.InsideRound
257
+ stack.push(State.AfterQuery)
258
+ } else if ((next = part.match(RE_COMMA))) {
259
+ token = TokenType.Punctuation
260
+ state = State.AfterQuery
261
+ } else if ((next = part.match(RE_DOUBLE_QUOTE))) {
262
+ token = TokenType.Punctuation
263
+ state = State.InsideDoubleQuoteString
264
+ stack.push(State.AfterQuery)
265
+ } else if ((next = part.match(RE_SEMICOLON))) {
266
+ token = TokenType.Punctuation
267
+ state = stack.pop() || State.TopLevelContent
268
+ } else {
269
+ part
270
+ throw new Error('no')
271
+ }
272
+ break
273
+ case State.AfterQueryWithRules:
274
+ if ((next = part.match(RE_WHITESPACE))) {
275
+ token = TokenType.Whitespace
276
+ state = State.AfterQueryWithRules
277
+ } else if ((next = part.match(RE_CURLY_OPEN))) {
278
+ token = TokenType.Punctuation
279
+ state = State.InsideSelector
280
+ } else {
281
+ throw new Error('no')
282
+ }
283
+ break
284
+ case State.InsideBlockComment:
285
+ if ((next = part.match(RE_BLOCK_COMMENT_END))) {
286
+ token = TokenType.Comment
287
+ state = stack.pop() || State.TopLevelContent
288
+ } else if ((next = part.match(RE_BLOCK_COMMENT_CONTENT))) {
289
+ token = TokenType.Comment
290
+ state = State.InsideBlockComment
291
+ } else {
292
+ throw new Error('no')
293
+ }
294
+ break
295
+ // TODO support css nesting https://www.w3.org/TR/css-nesting-1/
296
+ case State.InsideSelector:
297
+ if ((next = part.match(RE_WHITESPACE))) {
298
+ token = TokenType.Whitespace
299
+ state = State.InsideSelector
300
+ } else if ((next = part.match(RE_PROPERTY_NAME))) {
301
+ token = TokenType.CssPropertyName
302
+ state = State.AfterPropertyName
303
+ if (next[0].startsWith('--')) {
304
+ token = TokenType.Variable
305
+ }
306
+ } else if ((next = part.match(RE_BLOCK_COMMENT_START))) {
307
+ token = TokenType.Comment
308
+ state = State.InsideBlockComment
309
+ stack.push(State.InsideSelector)
310
+ } else if ((next = part.match(RE_STAR))) {
311
+ token = TokenType.Punctuation
312
+ state = State.InsideSelector
313
+ } else if ((next = part.match(RE_LINE_COMMENT))) {
314
+ token = TokenType.Comment
315
+ state = State.InsideSelector
316
+ } else if ((next = part.match(RE_ANYTHING_UNTIL_CLOSE_BRACE))) {
317
+ token = TokenType.Unknown
318
+ state = State.InsideSelector
319
+ } else if ((next = part.match(RE_CURLY_CLOSE))) {
320
+ token = TokenType.CurlyClose
321
+ state = State.TopLevelContent
322
+ } else {
323
+ throw new Error('no')
324
+ }
325
+ break
326
+ case State.AfterPropertyName:
327
+ if ((next = part.match(RE_COLON))) {
328
+ token = TokenType.CssPropertyColon
329
+ state = State.AfterPropertyNameAfterColon
330
+ } else if ((next = part.match(RE_CURLY_CLOSE))) {
331
+ token = TokenType.CurlyClose
332
+ state = State.TopLevelContent
333
+ } else if ((next = part.match(RE_WHITESPACE))) {
334
+ token = TokenType.Whitespace
335
+ state = State.AfterPropertyName
336
+ } else if ((next = part.match(RE_NUMERIC))) {
337
+ token = TokenType.Numeric
338
+ state = State.AfterPropertyNameAfterColon
339
+ } else if ((next = part.match(RE_PROPERTY_NAME))) {
340
+ token = TokenType.CssPropertyName
341
+ state = State.AfterPropertyName
342
+ } else if ((next = part.match(RE_ANYTHING_UNTIL_CLOSE_BRACE))) {
343
+ token = TokenType.Unknown
344
+ state = State.InsideSelector
345
+ } else {
346
+ tokens
347
+ part //?
348
+ throw new Error('no')
349
+ }
350
+ break
351
+ case State.AfterPropertyNameAfterColon:
352
+ if ((next = part.match(RE_WHITESPACE))) {
353
+ token = TokenType.Whitespace
354
+ state = State.AfterPropertyNameAfterColon
355
+ } else if ((next = part.match(RE_NUMERIC))) {
356
+ token = TokenType.Numeric
357
+ state = State.AfterPropertyNameAfterColon
358
+ } else if ((next = part.match(RE_FUNCTION))) {
359
+ token = TokenType.FuntionName
360
+ state = State.AfterFunctionName
361
+ } else if ((next = part.match(RE_FUNCTION))) {
362
+ token = TokenType.FuntionName
363
+ state = State.AfterFunctionName
364
+ } else if ((next = part.match(RE_SINGLE_QUOTE))) {
365
+ token = TokenType.Punctuation
366
+ state = State.InsideSingleQuoteString
367
+ stack.push(State.AfterPropertyNameAfterColon)
368
+ } else if ((next = part.match(RE_DOUBLE_QUOTE))) {
369
+ token = TokenType.Punctuation
370
+ state = State.InsideDoubleQuoteString
371
+ stack.push(State.AfterPropertyNameAfterColon)
372
+ } else if ((next = part.match(RE_PROPERTY_VALUE_SHORT))) {
373
+ token = TokenType.CssPropertyValue
374
+ state = State.AfterPropertyNameAfterColon
375
+ } else if ((next = part.match(RE_SEMICOLON))) {
376
+ token = TokenType.Punctuation
377
+ state = State.InsideSelector
378
+ } else if ((next = part.match(RE_PROPERTY_VALUE))) {
379
+ token = TokenType.CssPropertyValue
380
+ state = State.AfterPropertyNameAfterColon
381
+ } else if ((next = part.match(RE_CURLY_CLOSE))) {
382
+ token = TokenType.Punctuation
383
+ state = State.TopLevelContent
384
+ } else {
385
+ part
386
+ throw new Error('no')
387
+ }
388
+ break
389
+ case State.InsidePseudoSelector:
390
+ if ((next = part.match(RE_PSEUDO_SELECTOR_CONTENT))) {
391
+ token = TokenType.CssSelector
392
+ state = State.InsidePseudoSelector
393
+ } else if ((next = part.match(RE_ROUND_CLOSE))) {
394
+ token = TokenType.Punctuation
395
+ state = State.AfterSelector
396
+ } else {
397
+ throw new Error('no')
398
+ }
399
+ break
400
+ case State.InsideRound:
401
+ if ((next = part.match(RE_QUERY_CONTENT))) {
402
+ token = TokenType.Text
403
+ state = State.InsideRound
404
+ } else if ((next = part.match(RE_ROUND_CLOSE))) {
405
+ token = TokenType.Punctuation
406
+ state = stack.pop()
407
+ } else {
408
+ throw new Error('no')
409
+ }
410
+ break
411
+ case State.InsideAttributeSelector:
412
+ if ((next = part.match(RE_ATTRIBUTE_SELECTOR_CONTENT))) {
413
+ token = TokenType.CssSelector
414
+ state = State.InsideAttributeSelector
415
+ } else if ((next = part.match(RE_SQUARE_CLOSE))) {
416
+ token = TokenType.Punctuation
417
+ state = State.AfterSelector
418
+ } else {
419
+ throw new Error('no')
420
+ }
421
+ break
422
+ case State.AfterFunctionName:
423
+ if ((next = part.match(RE_ROUND_OPEN))) {
424
+ token = TokenType.Punctuation
425
+ state = State.AfterFunctionNameInsideArguments
426
+ } else if ((next = part.match(RE_NUMERIC))) {
427
+ token = TokenType.Numeric
428
+ state = State.AfterFunctionName
429
+ } else if ((next = part.match(RE_WHITESPACE))) {
430
+ token = TokenType.Whitespace
431
+ state = State.AfterFunctionName
432
+ } else if ((next = part.match(RE_ROUND_CLOSE))) {
433
+ token = TokenType.Punctuation
434
+ state = State.AfterFunctionName
435
+ } else if ((next = part.match(RE_SEMICOLON))) {
436
+ token = TokenType.Punctuation
437
+ state = State.InsideSelector
438
+ } else if ((next = part.match(RE_COMMA))) {
439
+ token = TokenType.Punctuation
440
+ state = State.AfterFunctionName
441
+ } else if ((next = part.match(RE_FUNCTION))) {
442
+ token = TokenType.FuntionName
443
+ state = State.AfterFunctionName
444
+ } else if ((next = part.match(RE_VARIABLE_NAME))) {
445
+ token = TokenType.Variable
446
+ state = State.AfterFunctionName
447
+ } else if ((next = part.match(RE_PERCENT))) {
448
+ token = TokenType.CssPropertyValue
449
+ state = State.AfterFunctionName
450
+ } else if ((next = part.match(RE_DOUBLE_QUOTE))) {
451
+ token = TokenType.Punctuation
452
+ state = State.InsideDoubleQuoteString
453
+ stack.push(State.AfterFunctionName)
454
+ } else if ((next = part.match(RE_SINGLE_QUOTE))) {
455
+ token = TokenType.Punctuation
456
+ state = State.InsideSingleQuoteString
457
+ stack.push(State.AfterFunctionName)
458
+ } else if ((next = part.match(RE_PROPERTY_VALUE_SHORT))) {
459
+ token = TokenType.CssPropertyValue
460
+ state = State.AfterFunctionName
461
+ } else if ((next = part.match(RE_CURLY_CLOSE))) {
462
+ token = TokenType.Punctuation
463
+ state = State.TopLevelContent
464
+ } else {
465
+ part
466
+ throw new Error('no')
467
+ }
468
+ break
469
+ case State.AfterFunctionNameInsideArguments:
470
+ if ((next = part.match(RE_ROUND_OPEN))) {
471
+ token = TokenType.Punctuation
472
+ state = State.AfterFunctionName
473
+ } else if ((next = part.match(RE_NUMERIC))) {
474
+ token = TokenType.Numeric
475
+ state = State.AfterFunctionName
476
+ } else if ((next = part.match(RE_WHITESPACE))) {
477
+ token = TokenType.Whitespace
478
+ state = State.AfterFunctionName
479
+ } else if ((next = part.match(RE_ROUND_CLOSE))) {
480
+ token = TokenType.Punctuation
481
+ state = stack.pop() || State.InsideSelector
482
+ } else if ((next = part.match(RE_SEMICOLON))) {
483
+ token = TokenType.Punctuation
484
+ state = State.InsideSelector
485
+ } else if ((next = part.match(RE_COMMA))) {
486
+ token = TokenType.Punctuation
487
+ state = State.AfterFunctionName
488
+ } else if ((next = part.match(RE_FUNCTION))) {
489
+ token = TokenType.FuntionName
490
+ state = State.AfterFunctionName
491
+ } else if ((next = part.match(RE_VARIABLE_NAME))) {
492
+ token = TokenType.Variable
493
+ state = State.AfterFunctionName
494
+ } else if ((next = part.match(RE_PERCENT))) {
495
+ token = TokenType.CssPropertyValue
496
+ state = State.AfterFunctionName
497
+ } else if ((next = part.match(RE_DOUBLE_QUOTE))) {
498
+ token = TokenType.Punctuation
499
+ state = State.InsideDoubleQuoteString
500
+ stack.push(State.AfterFunctionName)
501
+ } else if ((next = part.match(RE_SINGLE_QUOTE))) {
502
+ token = TokenType.Punctuation
503
+ state = State.InsideSingleQuoteString
504
+ stack.push(State.AfterFunctionName)
505
+ } else if ((next = part.match(RE_PROPERTY_VALUE_INSIDE_FUNCTION))) {
506
+ token = TokenType.CssPropertyValue
507
+ state = State.AfterFunctionName
508
+ } else if ((next = part.match(RE_CURLY_CLOSE))) {
509
+ token = TokenType.Punctuation
510
+ state = stack.pop() || State.TopLevelContent
511
+ } else {
512
+ part
513
+ throw new Error('no')
514
+ }
515
+ break
516
+ case State.InsideDoubleQuoteString:
517
+ if ((next = part.match(RE_DOUBLE_QUOTE))) {
518
+ token = TokenType.Punctuation
519
+ state = stack.pop() || State.TopLevelContent
520
+ } else if ((next = part.match(RE_STRING_DOUBLE_QUOTE_CONTENT))) {
521
+ token = TokenType.String
522
+ state = State.InsideDoubleQuoteString
523
+ } else {
524
+ throw new Error('no')
525
+ }
526
+ break
527
+ case State.AfterKeywordImport:
528
+ if ((next = part.match(RE_WHITESPACE))) {
529
+ token = TokenType.Whitespace
530
+ state = State.AfterKeywordImport
531
+ } else if ((next = part.match(RE_SINGLE_QUOTE))) {
532
+ token = TokenType.Punctuation
533
+ state = State.InsideSingleQuoteString
534
+ } else if ((next = part.match(RE_DOUBLE_QUOTE))) {
535
+ token = TokenType.Punctuation
536
+ state = State.InsideDoubleQuoteString
537
+ } else {
538
+ throw new Error('no')
539
+ }
540
+ break
541
+ case State.InsideSingleQuoteString:
542
+ if ((next = part.match(RE_SINGLE_QUOTE))) {
543
+ token = TokenType.Punctuation
544
+ state = stack.pop() || State.TopLevelContent
545
+ } else if ((next = part.match(RE_STRING_SINGLE_QUOTE_CONTENT))) {
546
+ token = TokenType.String
547
+ state = State.InsideSingleQuoteString
548
+ } else {
549
+ throw new Error('no')
550
+ }
551
+ break
552
+ default:
553
+ console.log({ state, line })
554
+ throw new Error('no')
555
+ }
556
+ const tokenLength = next[0].length
557
+ index += tokenLength
558
+ tokens.push(token, tokenLength)
559
+ }
560
+ if (state === State.AfterPropertyName) {
561
+ state = State.InsideSelector
562
+ }
24
563
  return {
25
- state: 1,
564
+ state,
26
565
  tokens,
566
+ stack,
27
567
  }
28
568
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.16.1",
3
+ "version": "0.16.3",
4
4
  "description": "Utility package for @lvce-editor/server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -17,9 +17,9 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@babel/code-frame": "^7.22.5",
20
- "@lvce-editor/extension-host": "0.16.1",
21
- "@lvce-editor/extension-host-helper-process": "0.16.1",
22
- "@lvce-editor/pty-host": "0.16.1",
20
+ "@lvce-editor/extension-host": "0.16.3",
21
+ "@lvce-editor/extension-host-helper-process": "0.16.3",
22
+ "@lvce-editor/pty-host": "0.16.3",
23
23
  "debug": "^4.3.4",
24
24
  "execa": "^7.1.1",
25
25
  "exit-hook": "^3.2.0",
@@ -0,0 +1,26 @@
1
+ import { Session } from 'node:inspector'
2
+ import * as Timeout from '../Timeout/Timeout.js'
3
+ import { writeFileSync } from 'node:fs'
4
+
5
+ export const createProfile = async () => {
6
+ const session = new Session()
7
+ session.connect()
8
+
9
+ await new Promise((resolve) => {
10
+ session.post('Profiler.enable', () => {
11
+ session.post('Profiler.start', () => {
12
+ // Invoke business logic under measurement here...
13
+
14
+ Timeout.setTimeout(() => {
15
+ session.post('Profiler.stop', (error, { profile }) => {
16
+ // Write profile to disk, upload, etc.
17
+ if (!error) {
18
+ writeFileSync('/tmp/vscode-profile.cpuprofile', JSON.stringify(profile))
19
+ }
20
+ })
21
+ }, 15000)
22
+ // some time later...
23
+ })
24
+ })
25
+ })
26
+ }
@@ -0,0 +1,5 @@
1
+ import * as Crash from './Crash.js'
2
+
3
+ export const Commands = {
4
+ crashSharedProcess: Crash.crashSharedProcess,
5
+ }
@@ -0,0 +1,9 @@
1
+ import * as Timeout from '../Timeout/Timeout.js'
2
+
3
+ const handleTimeout = () => {
4
+ throw new Error('oops')
5
+ }
6
+
7
+ export const crashSharedProcess = () => {
8
+ Timeout.setTimeout(handleTimeout, 0)
9
+ }
@@ -1,13 +1,15 @@
1
+ import * as CpuProfile from '../CpuProfile/CpuProfile.js'
2
+ import * as Crash from '../Crash/Crash.js'
3
+ import * as HeapSnapshot from '../HeapSnapshot/HeapSnapshot.js'
1
4
  import * as Developer from './Developer.js'
2
5
 
3
6
  export const name = 'Developer'
4
7
 
5
- // prettier-ignore
6
8
  export const Commands = {
7
9
  allocateMemory: Developer.allocateMemory,
8
- crashSharedProcess: Developer.crashSharedProcess,
9
- createHeapSnapshot: Developer.createHeapSnapshot,
10
- createProfile: Developer.createProfile,
10
+ createProfile: CpuProfile.createProfile,
11
+ createHeapSnapshot: HeapSnapshot.createHeapSnapshot,
12
+ crashSharedProcess: Crash.crashSharedProcess,
11
13
  getNodeStartupTime: Developer.getNodeStartupTiming,
12
14
  getNodeStartupTiming: Developer.getNodeStartupTiming,
13
15
  sharedProcessMemoryUsage: Developer.sharedProcessMemoryUsage,
@@ -1,22 +1,14 @@
1
- import { createWriteStream, writeFileSync } from 'node:fs'
2
1
  import { performance } from 'node:perf_hooks'
3
2
  import * as ExtensionHost from '../ExtensionHost/ExtensionHost.js'
4
3
  import * as Process from '../Process/Process.js'
5
- import * as Timeout from '../Timeout/Timeout.js'
6
4
 
7
- export const measureLatencyBetweenExtensionHostAndSharedProcess = async (
8
- socket,
9
- id
10
- ) => {
5
+ export const measureLatencyBetweenExtensionHostAndSharedProcess = async (socket, id) => {
11
6
  // TODO lazy load extension host
12
7
  const latency = await ExtensionHost.measureLatency()
13
8
  socket.send([/* callback */ id, /* latency */ latency])
14
9
  }
15
10
 
16
- export const measureLatencyBetweenSharedProcessAndRendererProcess = async (
17
- socket,
18
- id
19
- ) => {
11
+ export const measureLatencyBetweenSharedProcessAndRendererProcess = async (socket, id) => {
20
12
  // const start = performance.now()
21
13
  // await new Promise((resolve) => {
22
14
  // const callbackId = Callback.register(resolve)
@@ -76,13 +68,6 @@ export const allocateMemory = () => {
76
68
  globalThis.arr = array
77
69
  }
78
70
 
79
- /* istanbul ignore next */
80
- export const crashSharedProcess = () => {
81
- Timeout.setTimeout(() => {
82
- throw new Error('oops')
83
- }, 0)
84
- }
85
-
86
71
  export const osStats = () => {
87
72
  // TODO stats
88
73
  // - os name
@@ -92,43 +77,3 @@ export const osStats = () => {
92
77
  // - cpu temperature
93
78
  // - network usage
94
79
  }
95
-
96
- /* istanbul ignore next */
97
- export const createHeapSnapshot = async () => {
98
- const { getHeapSnapshot } = await import('node:v8')
99
- const { pipeline } = await import('node:stream/promises')
100
- await pipeline(
101
- getHeapSnapshot(),
102
- // TODO get tmp dir from env
103
- createWriteStream(`/tmp/vscode-${Date.now()}.heapsnapshot`)
104
- )
105
- }
106
-
107
- export const createProfile = async () => {
108
- const inspector = await import('node:inspector')
109
- const session = new inspector.Session()
110
- session.connect()
111
-
112
- await new Promise((resolve) => {
113
- session.post('Profiler.enable', () => {
114
- session.post('Profiler.start', () => {
115
- // Invoke business logic under measurement here...
116
-
117
- Timeout.setTimeout(() => {
118
- session.post('Profiler.stop', (error, { profile }) => {
119
- // Write profile to disk, upload, etc.
120
- if (!error) {
121
- writeFileSync(
122
- '/tmp/vscode-profile.cpuprofile',
123
- JSON.stringify(profile)
124
- )
125
- }
126
- })
127
- }, 15000)
128
- // some time later...
129
- })
130
- })
131
- })
132
- }
133
-
134
- // require('inspector').open()
@@ -1,56 +1,10 @@
1
1
  import * as ExtensionInstallType from '../ExtensionInstallType/ExtensionInstallType.js'
2
2
  import * as Path from '../Path/Path.js'
3
-
4
- const parseUrlGithub = (input) => {
5
- const parts = input.split('/')
6
- const slashCount = parts.length
7
- if (slashCount === 5) {
8
- const user = parts[3]
9
- const repo = parts[4]
10
- return {
11
- type: ExtensionInstallType.GithubRepository,
12
- options: {
13
- user,
14
- repo,
15
- branch: 'HEAD',
16
- },
17
- }
18
- }
19
- if (slashCount === 7) {
20
- const user = parts[3]
21
- const repo = parts[4]
22
- const type = parts[5]
23
- const commit = parts[6]
24
- if (type === 'tree') {
25
- return {
26
- type: ExtensionInstallType.GithubRepository,
27
- options: {
28
- user,
29
- repo,
30
- branch: commit,
31
- },
32
- }
33
- }
34
- if (type === 'pull') {
35
- return {
36
- type: ExtensionInstallType.ParsingError,
37
- options: {
38
- message: 'Cannot download from Pull Request',
39
- },
40
- }
41
- }
42
- }
43
- return {
44
- type: ExtensionInstallType.ParsingError,
45
- options: {
46
- message: 'Failed to parse github url',
47
- },
48
- }
49
- }
3
+ import * as ParseUrlGithub from '../ParseUrlGithub/ParseUrlGithub.js'
50
4
 
51
5
  const parseUrl = (input) => {
52
6
  if (input.startsWith('https://github.com')) {
53
- return parseUrlGithub(input)
7
+ return ParseUrlGithub.parseUrlGithub(input)
54
8
  }
55
9
  if (input.endsWith('.tar.br')) {
56
10
  return {
@@ -0,0 +1,7 @@
1
+ import * as HeapSnapshot from './HeapSnapshot.js'
2
+
3
+ export const name = 'HeapSnapshot'
4
+
5
+ export const Commands = {
6
+ createHeapSnapshot: HeapSnapshot.createHeapSnapshot,
7
+ }
@@ -0,0 +1,11 @@
1
+ import { createWriteStream } from 'node:fs'
2
+ import { getHeapSnapshot } from 'node:v8'
3
+ import { pipeline } from 'node:stream/promises'
4
+
5
+ export const createHeapSnapshot = async () => {
6
+ await pipeline(
7
+ getHeapSnapshot(),
8
+ // TODO get tmp dir from env
9
+ createWriteStream(`/tmp/vscode-${Date.now()}.heapsnapshot`)
10
+ )
11
+ }
@@ -0,0 +1,48 @@
1
+ import * as ExtensionInstallType from '../ExtensionInstallType/ExtensionInstallType.js'
2
+
3
+ export const parseUrlGithub = (input) => {
4
+ const parts = input.split('/')
5
+ const slashCount = parts.length
6
+ if (slashCount === 5) {
7
+ const user = parts[3]
8
+ const repo = parts[4]
9
+ return {
10
+ type: ExtensionInstallType.GithubRepository,
11
+ options: {
12
+ user,
13
+ repo,
14
+ branch: 'HEAD',
15
+ },
16
+ }
17
+ }
18
+ if (slashCount === 7) {
19
+ const user = parts[3]
20
+ const repo = parts[4]
21
+ const type = parts[5]
22
+ const commit = parts[6]
23
+ if (type === 'tree') {
24
+ return {
25
+ type: ExtensionInstallType.GithubRepository,
26
+ options: {
27
+ user,
28
+ repo,
29
+ branch: commit,
30
+ },
31
+ }
32
+ }
33
+ if (type === 'pull') {
34
+ return {
35
+ type: ExtensionInstallType.ParsingError,
36
+ options: {
37
+ message: 'Cannot download from Pull Request',
38
+ },
39
+ }
40
+ }
41
+ }
42
+ return {
43
+ type: ExtensionInstallType.ParsingError,
44
+ options: {
45
+ message: 'Failed to parse github url',
46
+ },
47
+ }
48
+ }
@@ -165,11 +165,11 @@ export const getSetupName = () => {
165
165
  return 'Lvce-Setup'
166
166
  }
167
167
 
168
- export const version = '0.16.1'
168
+ export const version = '0.16.3'
169
169
 
170
- export const commit = 'ebf15de'
170
+ export const commit = '6fbd9fc'
171
171
 
172
- export const date = '2023-07-03T13:14:03.000Z'
172
+ export const date = '2023-07-04T07:58:24.000Z'
173
173
 
174
174
  export const getVersion = () => {
175
175
  return version