Skip to content

Commit

Permalink
Execute functions and await promises
Browse files Browse the repository at this point in the history
  • Loading branch information
NoriSte committed Mar 31, 2024
1 parent ad285c5 commit 8cedaa1
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 18 deletions.
12 changes: 12 additions & 0 deletions src/components/fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,15 @@ export function FormatStringifiedEvaluatedExpressions({ defaultValue, onChange }
</Checkbox>
)
}

export function ExecuteFunctionsAndAwaitPromises({ defaultValue, onChange }: { defaultValue: boolean; onChange: (newValue: boolean) => void }) {
const [value, setValue] = useState(defaultValue)

useOnChange(value, onChange)

return (
<Checkbox onValueChange={setValue} value={value}>
<Text>Execute functions and await promises</Text>
</Checkbox>
)
}
11 changes: 8 additions & 3 deletions src/core/createSelectAndInspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export function createSelectAndInspect(params: Params) {
break
}

case 'hideExpressionErrorsChanged':
currentConfiguration.hideExpressionErrors = event.value
logChange('Hide evaluated expressions errors changed')
break

case 'expressionsToEvaluateChanged':
currentConfiguration.expressionsToEvaluate = event.value
logChange('Expressions to evaluate changed')
Expand All @@ -79,9 +84,9 @@ export function createSelectAndInspect(params: Params) {
logChange('Stringify evaluated expressions changed')
break

case 'hideExpressionErrorsChanged':
currentConfiguration.hideExpressionErrors = event.value
logChange('Hide evaluated expressions errors changed')
case 'executeFunctionsAndAwaitPromisesChanged':
currentConfiguration.executeFunctionsAndAwaitPromises = event.value
logChange('Execute functions and await promises changed')
break

case 'formatStringifiedEvaluatedExpressionsChanged':
Expand Down
51 changes: 38 additions & 13 deletions src/core/processCurrentSelection.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
import { optional } from 'zod'

Check failure on line 1 in src/core/processCurrentSelection.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

'optional' is defined but never used
import { logExpression, logExpressionError, logStringifiedExpression } from '../utils/loggers'
import { stringifiedValueIsTheSame, stringifyError } from '../utils/generic'
import { isPromise, stringifiedValueIsTheSame, stringifyError } from '../utils/generic'
import type { LogOptions } from '../types'

export function processCurrentSelection(selection: ReadonlyArray<SceneNode>, configuration: LogOptions) {
processItems(
export async function processCurrentSelection(selection: ReadonlyArray<SceneNode>, configuration: LogOptions) {
await processItems(
selection,
configuration,
)
}

function processItems(items: readonly unknown[], logOptions: LogOptions) {
async function processItems(items: readonly unknown[], logOptions: LogOptions) {
for (const item of items) {
processItem(
await processItem(
item,
logOptions,
)
}
}

function evaluateExpression(item: unknown, expression: string) {
function evaluateExpression(item: unknown, expression: string, options: { invokeFunctions: boolean }) {
const { invokeFunctions } = options
// eslint-disable-next-line no-new-func
return new Function('obj', `return obj.${expression}`)(item)
return new Function('obj', `
function evaluator(obj) {
let value = obj.${expression}
if(typeof value === 'function' && ${invokeFunctions}) {
return obj.${expression}()
}
return value
}
return evaluator(obj)
`)(item)
}

function processItem(item: unknown, logOptions: LogOptions) {
async function processItem(item: unknown, logOptions: LogOptions) {
console.log(item)

const expressions = logOptions.expressionsToEvaluate.split(',')
Expand All @@ -32,23 +46,34 @@ function processItem(item: unknown, logOptions: LogOptions) {
const trimmedExpression = expression.trim()
if (expression === '')
continue
processExpression(item, trimmedExpression, logOptions)
await processExpression(item, trimmedExpression, logOptions)
}
}

function processExpression(
async function processExpression(
item: unknown,
expression: string,
logOptions: LogOptions,
) {
const { stringifyEvaluatedExpressions, hideExpressionErrors, formatStringifiedEvaluatedExpressions } = logOptions
const { stringifyEvaluatedExpressions, hideExpressionErrors, formatStringifiedEvaluatedExpressions, executeFunctionsAndAwaitPromises } = logOptions
let value
let stringifiedValue = ''
let errored = false

try {
value = evaluateExpression(item, expression)
logExpression(expression, value)
value = evaluateExpression(item, expression, { invokeFunctions: executeFunctionsAndAwaitPromises })
if (executeFunctionsAndAwaitPromises) {
if (isPromise(value)) {
const resolvedValue = await value
logExpression(expression, resolvedValue)
}
else {
logExpression(expression, value)
}
}
else {
logExpression(expression, value)
}
}
catch (e) {
errored = true
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const defaultConfiguration: LogOptions = {
expressionsToEvaluate: '',
hideExpressionErrors: false,
stringifyEvaluatedExpressions: false,
executeFunctionsAndAwaitPromises: false,
formatStringifiedEvaluatedExpressions: false,
}

Expand Down
9 changes: 7 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const logOptionsSchema = z.object({
expressionsToEvaluate: z.string(),
hideExpressionErrors: z.boolean(),
stringifyEvaluatedExpressions: z.boolean(),
executeFunctionsAndAwaitPromises: z.boolean(),
formatStringifiedEvaluatedExpressions: z.boolean(),
})

Expand All @@ -37,6 +38,10 @@ export const uiEventSchema = z.union([
type: z.literal('enabledChanged'),
value: z.boolean(),
}),
z.object({
type: z.literal('hideExpressionErrorsChanged'),
value: z.boolean(),
}),
z.object({
type: z.literal('expressionsToEvaluateChanged'),
value: z.string(),
Expand All @@ -46,11 +51,11 @@ export const uiEventSchema = z.union([
value: z.boolean(),
}),
z.object({
type: z.literal('formatStringifiedEvaluatedExpressionsChanged'),
type: z.literal('executeFunctionsAndAwaitPromisesChanged'),
value: z.boolean(),
}),
z.object({
type: z.literal('hideExpressionErrorsChanged'),
type: z.literal('formatStringifiedEvaluatedExpressionsChanged'),
value: z.boolean(),
}),
])
Expand Down
10 changes: 10 additions & 0 deletions src/ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { type UiEvent, logOptionsSchema, serverEventSchema } from './types'

import {
EnabledDisabled,
ExecuteFunctionsAndAwaitPromises,
ExpressionsToEvaluate,
FormatStringifiedEvaluatedExpressions,
HideExpressionErrors,
Expand Down Expand Up @@ -97,13 +98,22 @@ function UI({ configuration }: { configuration: unknown }) {
emit('uiEvent', event)
}}
/>
</Columns>
<Columns space="extraLarge">
<FormatStringifiedEvaluatedExpressions
defaultValue={configurationRef.current.formatStringifiedEvaluatedExpressions}
onChange={(value) => {
const event: UiEvent = { type: 'formatStringifiedEvaluatedExpressionsChanged', value }
emit('uiEvent', event)
}}
/>
<ExecuteFunctionsAndAwaitPromises
defaultValue={configurationRef.current.executeFunctionsAndAwaitPromises}
onChange={(value) => {
const event: UiEvent = { type: 'executeFunctionsAndAwaitPromisesChanged', value }
emit('uiEvent', event)
}}
/>
</Columns>

<Button
Expand Down
4 changes: 4 additions & 0 deletions src/utils/generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ export function isEmptyArray(value: unknown) {
Array.isArray(value) && value.length === 0
)
}

export function isPromise(obj: unknown) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && 'then' in obj && typeof obj.then === 'function'
}

0 comments on commit 8cedaa1

Please sign in to comment.