|
1 |
| -import { |
2 |
| - type MarshalledDomNode, |
3 |
| - type ReplPayload, |
4 |
| - identifierNameFunctionMeta, |
5 |
| -} from '@jsrepl/shared-types' |
6 |
| -import { getBabel } from '../get-babel' |
| 1 | +import { type MarshalledDomNode, type ReplPayload } from '@jsrepl/shared-types' |
| 2 | +import { parseFunction } from './parse-function' |
7 | 3 | import * as utils from './payload-utils'
|
8 | 4 |
|
9 | 5 | const MAX_NESTING_LEVEL = 20
|
@@ -57,8 +53,12 @@ function _stringifyResult(
|
57 | 53 | return data?.caught ? `[ref *${data.index}] ` : ''
|
58 | 54 | }
|
59 | 55 |
|
60 |
| - function next(result: ReplPayload['result'], target: StringifyResultTarget): StringifyResult { |
61 |
| - return _stringifyResult(result, target, nestingLevel + 1, refs) |
| 56 | + function next( |
| 57 | + result: ReplPayload['result'], |
| 58 | + target: StringifyResultTarget, |
| 59 | + customNestingLevel?: number |
| 60 | + ): StringifyResult { |
| 61 | + return _stringifyResult(result, target, customNestingLevel ?? nestingLevel + 1, refs) |
62 | 62 | }
|
63 | 63 |
|
64 | 64 | function t(str: string, relativeIndexLevel: number) {
|
@@ -331,6 +331,29 @@ ${t('', 0)}}`
|
331 | 331 | return { value, type: 'promise', lang: 'js' }
|
332 | 332 | }
|
333 | 333 |
|
| 334 | + if (utils.isMarshalledProxy(result)) { |
| 335 | + const { target: targetObj, handler } = result.__meta__ |
| 336 | + let value: string |
| 337 | + if (target === 'decor') { |
| 338 | + const targetStr = next(targetObj, target, nestingLevel).value |
| 339 | + const handlerStr = next(handler, target).value |
| 340 | + value = `Proxy(${targetStr}) ${handlerStr}` |
| 341 | + } else { |
| 342 | + const targetStr = next(targetObj, target).value |
| 343 | + const handlerStr = next(handler, target).value |
| 344 | + value = `Proxy { |
| 345 | +${t('', 1)}[[Target]]: ${targetStr}, |
| 346 | +${t('', 1)}[[Handler]]: ${handlerStr} |
| 347 | +${t('', 0)}}` |
| 348 | + } |
| 349 | + |
| 350 | + return { |
| 351 | + value, |
| 352 | + type: 'proxy', |
| 353 | + lang: 'js', |
| 354 | + } |
| 355 | + } |
| 356 | + |
334 | 357 | if (utils.isMarshalledObject(result)) {
|
335 | 358 | const releaseRef = putRef(result)
|
336 | 359 | const { __meta__: meta, ...props } = result
|
@@ -388,101 +411,6 @@ ${t('', 0)}}`
|
388 | 411 | }
|
389 | 412 | }
|
390 | 413 |
|
391 |
| -// Let babel to parse this madness. |
392 |
| -// - function (arg1, arg2) {} |
393 |
| -// - async function (arg1, arg2) {} |
394 |
| -// - function name(arg1, arg2) {} |
395 |
| -// - async function name(arg1, arg2) {} |
396 |
| -// - function name(arg1, arg2 = 123, ...args) {} |
397 |
| -// - () => {} |
398 |
| -// - async () => {} |
399 |
| -// - args1 => {} |
400 |
| -// - async args1 => {} |
401 |
| -// - (args1, args2) => {} |
402 |
| -// - async (args1, args2) => {} |
403 |
| -// - function ({ jhkhj, asdad = 123 } = {}) {} |
404 |
| -// - () => 7 |
405 |
| -// - function (asd = adsasd({})) { ... } |
406 |
| -function parseFunction( |
407 |
| - str: string, |
408 |
| - _isOriginalSource = false |
409 |
| -): { |
410 |
| - name: string |
411 |
| - args: string |
412 |
| - isAsync: boolean |
413 |
| - isArrow: boolean |
414 |
| - origSource: string | null |
415 |
| -} | null { |
416 |
| - const babel = getBabel()[0].value! |
417 |
| - |
418 |
| - // @ts-expect-error Babel standalone: https://babeljs.io/docs/babel-standalone#internal-packages |
419 |
| - const { parser } = babel.packages as { parser: typeof import('@babel/parser') } |
420 |
| - |
421 |
| - let ast: ReturnType<typeof parser.parseExpression> |
422 |
| - |
423 |
| - try { |
424 |
| - // ArrowFunctionExpression | FunctionExpression |
425 |
| - ast = parser.parseExpression(str) |
426 |
| - } catch { |
427 |
| - return null |
428 |
| - } |
429 |
| - |
430 |
| - let origSource: string | null = null |
431 |
| - |
432 |
| - if (!_isOriginalSource) { |
433 |
| - origSource = getFunctionOriginalSource(ast) |
434 |
| - if (origSource) { |
435 |
| - return parseFunction(origSource, true) |
436 |
| - } |
437 |
| - } else { |
438 |
| - origSource = str |
439 |
| - } |
440 |
| - |
441 |
| - if (ast.type === 'ArrowFunctionExpression') { |
442 |
| - return { |
443 |
| - name: '', |
444 |
| - args: ast.params.map((param) => str.slice(param.start!, param.end!)).join(', '), |
445 |
| - isAsync: ast.async, |
446 |
| - isArrow: true, |
447 |
| - origSource, |
448 |
| - } |
449 |
| - } |
450 |
| - |
451 |
| - if (ast.type === 'FunctionExpression') { |
452 |
| - return { |
453 |
| - name: ast.id?.name ?? '', |
454 |
| - args: ast.params.map((param) => str.slice(param.start!, param.end!)).join(', '), |
455 |
| - isAsync: ast.async, |
456 |
| - isArrow: false, |
457 |
| - origSource, |
458 |
| - } |
459 |
| - } |
460 |
| - |
461 |
| - return null |
462 |
| -} |
463 |
| - |
464 |
| -function getFunctionOriginalSource( |
465 |
| - ast: ReturnType<typeof import('@babel/parser').parseExpression> |
466 |
| -): string | null { |
467 |
| - if ( |
468 |
| - (ast.type === 'ArrowFunctionExpression' || ast.type === 'FunctionExpression') && |
469 |
| - ast.body.type === 'BlockStatement' |
470 |
| - ) { |
471 |
| - const node = ast.body.body[0] |
472 |
| - if ( |
473 |
| - node?.type === 'ExpressionStatement' && |
474 |
| - node.expression.type === 'CallExpression' && |
475 |
| - node.expression.callee.type === 'Identifier' && |
476 |
| - node.expression.callee.name === identifierNameFunctionMeta && |
477 |
| - node.expression.arguments[0]?.type === 'StringLiteral' |
478 |
| - ) { |
479 |
| - return node.expression.arguments[0].value |
480 |
| - } |
481 |
| - } |
482 |
| - |
483 |
| - return null |
484 |
| -} |
485 |
| - |
486 | 414 | function stringifyDomNodeShort(result: MarshalledDomNode): string {
|
487 | 415 | const meta = result.__meta__
|
488 | 416 | const idAttr = meta.attributes.find((attr) => attr.name === 'id')
|
|
0 commit comments