This commit is contained in:
Yamozha
2021-04-02 02:24:13 +03:00
parent c23950b545
commit 7256d79e2c
31493 changed files with 3036630 additions and 0 deletions

11
node_modules/expo/build/logs/LogSerialization.d.ts generated vendored Normal file
View File

@ -0,0 +1,11 @@
import { LogData, LogLevel } from './RemoteLogging';
declare type SerializedData = {
body: LogData[];
includesStack: boolean;
};
export declare const EXPO_CONSOLE_METHOD_NAME = "__expoConsoleLog";
declare function serializeLogDataAsync(data: unknown[], level: LogLevel): Promise<SerializedData>;
declare const _default: {
serializeLogDataAsync: typeof serializeLogDataAsync;
};
export default _default;

178
node_modules/expo/build/logs/LogSerialization.js generated vendored Normal file
View File

@ -0,0 +1,178 @@
import Constants from 'expo-constants';
import prettyFormat from 'pretty-format';
import parseErrorStack from 'react-native/Libraries/Core/Devtools/parseErrorStack';
import symbolicateStackTrace from 'react-native/Libraries/Core/Devtools/symbolicateStackTrace';
import ReactNodeFormatter from './format/ReactNodeFormatter';
export const EXPO_CONSOLE_METHOD_NAME = '__expoConsoleLog';
async function serializeLogDataAsync(data, level) {
let serializedValues;
let includesStack = false;
if (_stackTraceLogsSupported()) {
if (_isUnhandledPromiseRejection(data, level)) {
const rawStack = data[0];
const syntheticError = { stack: rawStack };
const stack = await _symbolicateErrorAsync(syntheticError);
if (!stack.length) {
serializedValues = _stringifyLogData(data);
}
else {
// NOTE: This doesn't handle error messages with newlines
const errorMessage = rawStack.split('\n')[1];
serializedValues = [
{
message: `[Unhandled promise rejection: ${errorMessage}]`,
stack: _formatStack(stack),
},
];
includesStack = true;
}
}
else if (data.length === 1 && data[0] instanceof Error) {
// When there's only one argument to the log function and that argument is an error, we
// include the error's stack. If there's more than one argument then we don't include the
// stack because it's not easy to display nicely in our current UI.
const serializedError = await _serializeErrorAsync(data[0]);
serializedValues = [serializedError];
includesStack = serializedError.hasOwnProperty('stack');
}
else if (level === 'warn' || level === 'error') {
// For console.warn and console.error it is usually useful to know the stack that leads to the
// warning or error, so we provide this information to help out with debugging
const error = _captureConsoleStackTrace();
// ["hello", "world"] becomes "hello, world"
const errorMessage = _stringifyLogData(data).join(', ');
const serializedError = await _serializeErrorAsync(error, errorMessage);
serializedValues = [serializedError];
includesStack = serializedError.hasOwnProperty('stack');
}
else {
serializedValues = _stringifyLogData(data);
}
}
else {
serializedValues = _stringifyLogData(data);
}
return {
body: [...serializedValues],
includesStack,
};
}
function _stringifyLogData(data) {
return data.map(item => {
if (typeof item === 'string') {
return item;
}
else {
// define the max length for log msg to be first 10000 characters
const LOG_MESSAGE_MAX_LENGTH = 10000;
const result = prettyFormat(item, { plugins: [ReactNodeFormatter] });
// check the size of string returned
if (result.length > LOG_MESSAGE_MAX_LENGTH) {
let truncatedResult = result.substring(0, LOG_MESSAGE_MAX_LENGTH);
// truncate the result string to the max length
truncatedResult += `...(truncated to the first ${LOG_MESSAGE_MAX_LENGTH} characters)`;
return truncatedResult;
}
else {
return result;
}
}
});
}
async function _serializeErrorAsync(error, message) {
if (message == null) {
message = error.message;
}
if (!error.stack || !error.stack.length) {
return prettyFormat(error);
}
const stack = await _symbolicateErrorAsync(error);
const formattedStack = _formatStack(stack);
return { message, stack: formattedStack };
}
async function _symbolicateErrorAsync(error) {
const parsedStack = parseErrorStack(error);
let symbolicatedStack;
try {
// @ts-ignore: symbolicateStackTrace has different real/Flow declaration
// than the one in DefinitelyTyped.
symbolicatedStack = (await symbolicateStackTrace(parsedStack))?.stack ?? null;
}
catch (error) {
return parsedStack;
}
// In this context an unsymbolicated stack is better than no stack
if (!symbolicatedStack) {
return parsedStack;
}
// Clean the stack trace
return symbolicatedStack.map(_removeProjectRoot);
}
function _formatStack(stack) {
return stack
.map(frame => {
let line = `${frame.file}:${frame.lineNumber}`;
if (frame.column != null) {
line += `:${frame.column}`;
}
line += ` in ${frame.methodName}`;
return line;
})
.join('\n');
}
function _removeProjectRoot(frame) {
let filename = frame.file;
if (filename == null) {
return frame;
}
const projectRoot = _getProjectRoot();
if (projectRoot == null) {
return frame;
}
if (filename.startsWith(projectRoot)) {
filename = filename.substring(projectRoot.length);
if (filename[0] === '/' || filename[0] === '\\') {
filename = filename.substring(1);
}
frame.file = filename;
}
return frame;
}
/**
* Returns whether the development server that served this project supports logs with a stack trace.
* Specifically, the version of Expo CLI that includes `projectRoot` in the manifest also accepts
* payloads of the form:
*
* {
* includesStack: boolean, body: [{ message: string, stack: string }],
* }
*/
function _stackTraceLogsSupported() {
return !!(__DEV__ && _getProjectRoot());
}
function _isUnhandledPromiseRejection(data, level) {
return (level === 'warn' &&
typeof data[0] === 'string' &&
/^Possible Unhandled Promise Rejection/.test(data[0]));
}
function _captureConsoleStackTrace() {
try {
throw new Error();
}
catch (error) {
let stackLines = error.stack.split('\n');
const consoleMethodIndex = stackLines.findIndex(frame => frame.includes(EXPO_CONSOLE_METHOD_NAME));
if (consoleMethodIndex !== -1) {
stackLines = stackLines.slice(consoleMethodIndex + 1);
error.stack = stackLines.join('\n');
}
return error;
}
}
function _getProjectRoot() {
return Constants.manifest?.developer?.projectRoot ?? null;
}
export default {
serializeLogDataAsync,
};
//# sourceMappingURL=LogSerialization.js.map

1
node_modules/expo/build/logs/LogSerialization.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

2
node_modules/expo/build/logs/Logs.d.ts generated vendored Normal file
View File

@ -0,0 +1,2 @@
export declare function enableExpoCliLogging(): void;
export declare function disableExpoCliLogging(): void;

17
node_modules/expo/build/logs/Logs.js generated vendored Normal file
View File

@ -0,0 +1,17 @@
import RemoteConsole from './RemoteConsole';
let _originalConsole;
export function enableExpoCliLogging() {
if (_originalConsole) {
return;
}
_originalConsole = global.console;
global.console = RemoteConsole.createRemoteConsole(global.console);
}
export function disableExpoCliLogging() {
if (!_originalConsole) {
return;
}
global.console = _originalConsole;
_originalConsole = null;
}
//# sourceMappingURL=Logs.js.map

1
node_modules/expo/build/logs/Logs.js.map generated vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"Logs.js","sourceRoot":"","sources":["../../src/logs/Logs.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,IAAI,gBAAuC,CAAC;AAE5C,MAAM,UAAU,oBAAoB;IAClC,IAAI,gBAAgB,EAAE;QACpB,OAAO;KACR;IAED,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC;IAClC,MAAM,CAAC,OAAO,GAAG,aAAa,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC,gBAAgB,EAAE;QACrB,OAAO;KACR;IAED,MAAM,CAAC,OAAO,GAAG,gBAAgB,CAAC;IAClC,gBAAgB,GAAG,IAAI,CAAC;AAC1B,CAAC","sourcesContent":["import RemoteConsole from './RemoteConsole';\n\nlet _originalConsole: typeof console | null;\n\nexport function enableExpoCliLogging(): void {\n if (_originalConsole) {\n return;\n }\n\n _originalConsole = global.console;\n global.console = RemoteConsole.createRemoteConsole(global.console);\n}\n\nexport function disableExpoCliLogging(): void {\n if (!_originalConsole) {\n return;\n }\n\n global.console = _originalConsole;\n _originalConsole = null;\n}\n"]}

2
node_modules/expo/build/logs/Logs.web.d.ts generated vendored Normal file
View File

@ -0,0 +1,2 @@
export declare function enableExpoCliLogging(): void;
export declare function disableExpoCliLogging(): void;

7
node_modules/expo/build/logs/Logs.web.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
export function enableExpoCliLogging() {
console.warn('Expo.Logs.enableExpoCliLogging: is not supported on web');
}
export function disableExpoCliLogging() {
console.warn('Expo.Logs.disableExpoCliLogging: is not supported on web');
}
//# sourceMappingURL=Logs.web.js.map

1
node_modules/expo/build/logs/Logs.web.js.map generated vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"Logs.web.js","sourceRoot":"","sources":["../../src/logs/Logs.web.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB;IAClC,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;AAC1E,CAAC;AACD,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["export function enableExpoCliLogging(): void {\n console.warn('Expo.Logs.enableExpoCliLogging: is not supported on web');\n}\nexport function disableExpoCliLogging(): void {\n console.warn('Expo.Logs.disableExpoCliLogging: is not supported on web');\n}\n"]}

9
node_modules/expo/build/logs/RemoteConsole.d.ts generated vendored Normal file
View File

@ -0,0 +1,9 @@
/**
* Creates a console object that delegates calls to the specified underlying console and also sends
* the messages to the development environment over a remote connection.
*/
declare function createRemoteConsole(originalConsole: Console): Console;
declare const _default: {
createRemoteConsole: typeof createRemoteConsole;
};
export default _default;

101
node_modules/expo/build/logs/RemoteConsole.js generated vendored Normal file
View File

@ -0,0 +1,101 @@
import RemoteLogging from './RemoteLogging';
/**
* Creates a console object that delegates calls to the specified underlying console and also sends
* the messages to the development environment over a remote connection.
*/
function createRemoteConsole(originalConsole) {
let groupDepth = 0;
const enhancedConsole = Object.create(originalConsole);
// https://console.spec.whatwg.org/#debug
// Don't use a level below "info" because "debug" is intended for messages that shouldn't be shown
// to the developer
_defineConsoleLogMethod('debug', 'info');
// https://console.spec.whatwg.org/#log
_defineConsoleLogMethod('log', 'info');
// https://console.spec.whatwg.org/#info
_defineConsoleLogMethod('info', 'info');
// https://console.spec.whatwg.org/#warn
_defineConsoleLogMethod('warn', 'warn');
// https://console.spec.whatwg.org/#error
_defineConsoleLogMethod('error', 'error');
// https://console.spec.whatwg.org/#assert
enhancedConsole.assert = function assert(condition, ...data) {
if (originalConsole.assert) {
// @ts-ignore
originalConsole.assert(!!condition, ...data);
}
if (condition) {
return;
}
const assertionMessage = 'Assertion failed';
if (!data.length) {
data.push(assertionMessage);
}
else {
if (typeof data[0] !== 'string') {
data.unshift(assertionMessage);
}
else {
data[0] = `${assertionMessage}: ${data[0]}`;
}
}
_enqueueRemoteLog('error', {}, data);
};
// https://console.spec.whatwg.org/#group
enhancedConsole.group = function group(...data) {
if (originalConsole.group) {
// @ts-ignore
originalConsole.group(...data);
}
_enqueueRemoteLog('info', {}, data);
groupDepth++;
};
// https://console.spec.whatwg.org/#groupcollapsed
enhancedConsole.groupCollapsed = function groupCollapsed(...data) {
if (originalConsole.groupCollapsed) {
// @ts-ignore
originalConsole.groupCollapsed(...data);
}
_enqueueRemoteLog('info', { groupCollapsed: true }, data);
groupDepth++;
};
// https://console.spec.whatwg.org/#groupend
enhancedConsole.groupEnd = function groupEnd() {
if (originalConsole.groupEnd) {
originalConsole.groupEnd();
}
if (groupDepth > 0) {
groupDepth--;
}
_enqueueRemoteLog('info', { shouldHide: true }, []);
};
/**
* Defines a method in the `console.log()` family on the enhanced console
* instance
*/
function _defineConsoleLogMethod(name, level) {
enhancedConsole[name] = function __expoConsoleLog(...data) {
const originalMethod = originalConsole[name];
if (typeof originalMethod === 'function') {
originalMethod.apply(originalConsole, data);
}
_enqueueRemoteLog(level, {}, data);
};
}
/**
* Schedules the given log entry to be sent remotely in a safe way that handles all errors. This
* function is responsible for error handling because the console methods are synchronous but
* sending log messages is asynchronous, so this code (instead of the console methods) needs to be
* responsible for asynchronous errors.
*/
function _enqueueRemoteLog(level, additionalFields, data) {
RemoteLogging.enqueueRemoteLogAsync(level, { groupDepth, ...additionalFields }, data).catch(error => {
originalConsole.error(`There was a problem sending log messages to your development environment`, error);
});
}
return enhancedConsole;
}
export default {
createRemoteConsole,
};
//# sourceMappingURL=RemoteConsole.js.map

1
node_modules/expo/build/logs/RemoteConsole.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

28
node_modules/expo/build/logs/RemoteLogging.d.ts generated vendored Normal file
View File

@ -0,0 +1,28 @@
import { EventSubscription } from 'fbemitter';
export declare type LogLevel = 'debug' | 'info' | 'warn' | 'error';
export declare type LogEntryFields = {
shouldHide?: boolean;
groupDepth?: number;
groupCollapsed?: boolean;
};
export declare type LogData = string | LogErrorData;
export declare type LogErrorData = {
message: string;
stack: string;
};
declare type TransportErrorListener = (event: {
error: Error;
response?: Response;
}) => void;
declare function enqueueRemoteLogAsync(level: LogLevel, additionalFields: LogEntryFields, data: unknown[]): Promise<void>;
declare function addTransportErrorListener(listener: TransportErrorListener): EventSubscription;
declare const _default: {
enqueueRemoteLogAsync: typeof enqueueRemoteLogAsync;
addTransportErrorListener: typeof addTransportErrorListener;
};
export default _default;
/**
* Returns a promise that resolves when all entries in the log queue have been sent. This method is
* intended for testing only.
*/
export declare function __waitForEmptyLogQueueAsync(): Promise<void>;

135
node_modules/expo/build/logs/RemoteLogging.js generated vendored Normal file
View File

@ -0,0 +1,135 @@
import Constants from 'expo-constants';
import { EventEmitter } from 'fbemitter';
import invariant from 'invariant';
import { v4 as uuidv4 } from 'uuid';
import getInstallationIdAsync from '../environment/getInstallationIdAsync';
import LogSerialization from './LogSerialization';
const _sessionId = uuidv4();
const _logQueue = [];
const _transportEventEmitter = new EventEmitter();
let _logCounter = 0;
let _isSendingLogs = false;
let _completionPromise = null;
let _resolveCompletion = null;
async function enqueueRemoteLogAsync(level, additionalFields, data) {
if (_isReactNativeWarning(data)) {
// Remove the stack trace from the warning message since we'll capture our own
if (data.length === 0) {
throw new Error(`Warnings must include log arguments`);
}
const warning = data[0];
if (typeof warning !== 'string') {
throw new TypeError(`The log argument for a warning must be a string`);
}
const lines = warning.split('\n');
if (lines.length > 1 && /^\s+in /.test(lines[1])) {
data[0] = lines[0];
}
}
const { body, includesStack } = await LogSerialization.serializeLogDataAsync(data, level);
_logQueue.push({
count: _logCounter++,
level,
body,
includesStack,
...additionalFields,
});
// Send the logs asynchronously (system errors are emitted with transport error events) and throw an uncaught error
_sendRemoteLogsAsync().catch(error => {
setImmediate(() => {
throw error;
});
});
}
async function _sendRemoteLogsAsync() {
if (_isSendingLogs || !_logQueue.length) {
return;
}
// Our current transport policy is to send all of the pending log messages in one batch. If we opt
// for another policy (ex: throttling) this is where to to implement it.
const batch = _logQueue.splice(0);
const { logUrl } = Constants.manifest;
if (typeof logUrl !== 'string') {
throw new Error('The Expo project manifest must specify `logUrl`');
}
_isSendingLogs = true;
try {
await _sendNextLogBatchAsync(batch, logUrl);
}
finally {
_isSendingLogs = false;
}
if (_logQueue.length) {
return _sendRemoteLogsAsync();
}
else if (_resolveCompletion) {
_resolveCompletion();
}
}
async function _sendNextLogBatchAsync(batch, logUrl) {
let response;
const headers = {
'Content-Type': 'application/json',
Connection: 'keep-alive',
'Proxy-Connection': 'keep-alive',
Accept: 'application/json',
'Device-Id': await getInstallationIdAsync(),
'Session-Id': _sessionId,
};
if (Constants.deviceName) {
headers['Device-Name'] = Constants.deviceName;
}
try {
response = await fetch(logUrl, {
method: 'POST',
headers,
body: JSON.stringify(batch),
});
}
catch (error) {
_transportEventEmitter.emit('error', { error });
return;
}
const success = response.status >= 200 && response.status < 300;
if (!success) {
_transportEventEmitter.emit('error', {
error: new Error(`An HTTP error occurred when sending remote logs`),
response,
});
}
}
function addTransportErrorListener(listener) {
return _transportEventEmitter.addListener('error', listener);
}
function _isReactNativeWarning(data) {
// NOTE: RN does the same thing internally for YellowBox
const message = data[0];
return data.length === 1 && typeof message === 'string' && message.startsWith('Warning: ');
}
export default {
enqueueRemoteLogAsync,
addTransportErrorListener,
};
/**
* Returns a promise that resolves when all entries in the log queue have been sent. This method is
* intended for testing only.
*/
export function __waitForEmptyLogQueueAsync() {
if (_completionPromise) {
return _completionPromise;
}
if (!_isSendingLogs && !_logQueue.length) {
return Promise.resolve();
}
_completionPromise = new Promise(resolve => {
_resolveCompletion = () => {
invariant(!_isSendingLogs, `Must not be sending logs at completion`);
invariant(!_logQueue.length, `Log queue must be empty at completion`);
_completionPromise = null;
_resolveCompletion = null;
resolve();
};
});
return _completionPromise;
}
//# sourceMappingURL=RemoteLogging.js.map

1
node_modules/expo/build/logs/RemoteLogging.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
declare const _default: {
test(value: any): boolean;
serialize(node: any, config: any, indentation: any, depth: any, refs: any, printer: any): string;
};
/**
* A pretty-format plugin for React's FiberNode objects, which are very large trees that are too
* large and verbose to print.
*/
export default _default;

View File

@ -0,0 +1,35 @@
/**
* A pretty-format plugin for React's FiberNode objects, which are very large trees that are too
* large and verbose to print.
*/
export default {
test(value) {
return (value &&
value instanceof Object &&
value.hasOwnProperty('tag') &&
value.hasOwnProperty('key') &&
value.hasOwnProperty('type'));
},
serialize(node, config, indentation, depth, refs, printer) {
return `${config.min ? '' : 'FiberNode '}{${_printProperties(node, ['tag', 'key', 'type'], config, indentation, depth, refs, printer)}}`;
},
};
function _printProperties(object, keys, config, indentation, depth, refs, printer) {
let result = config.spacingOuter;
const propertyIndentation = indentation + config.indent;
for (let ii = 0; ii < keys.length; ii++) {
const key = keys[ii];
const name = printer(key, config, propertyIndentation, depth, refs);
const value = printer(object[key], config, propertyIndentation, depth, refs);
result += `${propertyIndentation}${name}: ${value}`;
if (ii < keys.length - 1) {
result += ',' + config.spacingInner;
}
else if (!config.min) {
result += ',';
}
}
result += config.spacingOuter + indentation;
return result;
}
//# sourceMappingURL=ReactNodeFormatter.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"ReactNodeFormatter.js","sourceRoot":"","sources":["../../../src/logs/format/ReactNodeFormatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAe;IACb,IAAI,CAAC,KAAU;QACb,OAAO,CACL,KAAK;YACL,KAAK,YAAY,MAAM;YACvB,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;YAC3B,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;YAC3B,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAC7B,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO;QACvD,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,gBAAgB,CAC1D,IAAI,EACJ,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EACtB,MAAM,EACN,WAAW,EACX,KAAK,EACL,IAAI,EACJ,OAAO,CACR,GAAG,CAAC;IACP,CAAC;CACF,CAAC;AAEF,SAAS,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO;IAC/E,IAAI,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;IACjC,MAAM,mBAAmB,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAExD,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAE7E,MAAM,IAAI,GAAG,mBAAmB,GAAG,IAAI,KAAK,KAAK,EAAE,CAAC;QAEpD,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;SACrC;aAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;YACtB,MAAM,IAAI,GAAG,CAAC;SACf;KACF;IAED,MAAM,IAAI,MAAM,CAAC,YAAY,GAAG,WAAW,CAAC;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * A pretty-format plugin for React's FiberNode objects, which are very large trees that are too\n * large and verbose to print.\n */\nexport default {\n test(value: any): boolean {\n return (\n value &&\n value instanceof Object &&\n value.hasOwnProperty('tag') &&\n value.hasOwnProperty('key') &&\n value.hasOwnProperty('type')\n );\n },\n\n serialize(node, config, indentation, depth, refs, printer): string {\n return `${config.min ? '' : 'FiberNode '}{${_printProperties(\n node,\n ['tag', 'key', 'type'],\n config,\n indentation,\n depth,\n refs,\n printer\n )}}`;\n },\n};\n\nfunction _printProperties(object, keys, config, indentation, depth, refs, printer) {\n let result = config.spacingOuter;\n const propertyIndentation = indentation + config.indent;\n\n for (let ii = 0; ii < keys.length; ii++) {\n const key = keys[ii];\n const name = printer(key, config, propertyIndentation, depth, refs);\n const value = printer(object[key], config, propertyIndentation, depth, refs);\n\n result += `${propertyIndentation}${name}: ${value}`;\n\n if (ii < keys.length - 1) {\n result += ',' + config.spacingInner;\n } else if (!config.min) {\n result += ',';\n }\n }\n\n result += config.spacingOuter + indentation;\n return result;\n}\n"]}