Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,15 @@

import esbuild, { analyzeMetafile } from "esbuild"

const sharedSettings = {
const esm = await esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
write: true,
outdir: "build",
metafile: true,
sourcemap: true,
}

const esm = await esbuild.build({
...sharedSettings,
format: "esm",
external: ["mutative"],
})

console.log(await analyzeMetafile(esm.metafile))

const cjs = await esbuild.build({
...sharedSettings,
format: "cjs",
entryNames: "index-cjs"
})

console.log(await analyzeMetafile(cjs.metafile))
24 changes: 11 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
"name": "@peacockproject/statemachine-parser",
"version": "6.2.0",
"description": "IOI state machine conditional parser.",
"main": "build/index-cjs.js",
"module": "build/index.js",
"type": "module",
"main": "build/index.js",
"types": "build/index.d.ts",
"homepage": "https://thepeacockproject.org",
"sideEffects": false,
"engines": {
"node": ">=16.3.0"
"node": ">=20"
},
"directories": {
"test": "tests",
Expand Down Expand Up @@ -40,30 +40,28 @@
"require": "./build/index-cjs.js"
},
"devDependencies": {
"@types/mocha": "^10.0.7",
"@types/node": "^20.14.8",
"c8": "^10.1.2",
"c8-as-nyc": "^1.1.11",
"call-spy": "^3.0.1",
"@vitest/coverage-v8": "^3.2.4",
"esbuild": "^0.25.0",
"esbuild-register": "^3.5.0",
"get-package-type": "^0.1.0",
"mocha": "^10.4.0",
"prettier": "^3.3.2",
"typescript": "^5.5.2"
"typescript": "^5.5.2",
"vitest": "^3.2.4"
},
"scripts": {
"prettier": "prettier --write \"**/*.{ts,md,json,js,cjs}\"",
"build": "tsc && node build.mjs",
"prepack": "yarn build",
"test": "mocha --require esbuild-register --extension js,ts,cjs,mjs tests",
"coverage": "c8 --reporter=lcov --reporter=text-summary --exclude=.yarn yarn test"
"test": "vitest",
"coverage": "vitest --coverage"
},
"prettier": {
"semi": false,
"tabWidth": 4
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"mutative": "^1.3.0"
}
}
108 changes: 64 additions & 44 deletions src/handleEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
* limitations under the License.
*/

import { handleActions, test } from "./index"
import { deepClone, findNamedChild, set } from "./utils"
import { test, handleActionsOnDraft } from "./index"
import { findNamedChild } from "./utils"
import {
HandleEventOptions,
HandleEventReturn,
InStateEventHandler,
StateMachineLike,
} from "./types"
import { create } from "mutative"


/**
* This function simulates an event happening, as if in game.
Expand Down Expand Up @@ -63,7 +65,7 @@ export function handleEvent<Context = unknown, Event = unknown>(
const hasTimerState = !!csObject.$timer

// ensure no circular references are present, and that this won't update the param by accident
let newContext = deepClone(context)
let newContext = context

const doEventHandler = (handler: InStateEventHandler) => {
// do we need to check conditions?
Expand Down Expand Up @@ -100,12 +102,17 @@ export function handleEvent<Context = unknown, Event = unknown>(
},
{
pushUniqueAction(reference, item) {
const referenceArray = findNamedChild(
reference,
newContext,
true,
)
item = findNamedChild(item, newContext, false)
const workingContext = {
...newContext,
...(definition.Constants || {}),
...(options.contractId && {
ContractId: options.contractId,
}),
Value: event,
}

const referenceArray = findNamedChild(reference, workingContext, true)
item = findNamedChild(item, workingContext, false)
log(
"action",
`Running pushUniqueAction on ${reference} with ${item}`,
Expand All @@ -119,9 +126,13 @@ export function handleEvent<Context = unknown, Event = unknown>(
return false
}

referenceArray.push(item)

set(newContext, reference, referenceArray)
// Actually modify the context using Mutative
newContext = create(newContext, (draft) => {
const draftArray = findNamedChild(reference, draft, true)
if (Array.isArray(draftArray) && !draftArray.includes(item)) {
draftArray.push(item)
}
})

return true
},
Expand All @@ -147,43 +158,52 @@ export function handleEvent<Context = unknown, Event = unknown>(
)
}

for (const actionSet of Actions as unknown[]) {
for (const action of Object.keys(actionSet)) {
newContext = handleActions(
{
[action]: actionSet[action],
},
{
...newContext,
...(definition.Constants || {}),
...(options.contractId && {
ContractId: options.contractId,
}),
Value: event,
},
{
originalContext: definition.Context ?? {},
},
)
}
// Special case: if the handler itself contains action keys and no Actions property,
// treat the handler as the actions
if (!handler.Actions && hasIrregularEventKeys) {
Actions = [handler]
}

// drop this specific event's value
if (newContext.hasOwnProperty("Value")) {
// @ts-expect-error
delete newContext.Value
// Create a working context with constants and event data
const workingContext = {
...newContext,
...(definition.Constants || {}),
...(options.contractId && {
ContractId: options.contractId,
}),
Value: event,
}

// drop this specific event's ContractId
if (newContext.hasOwnProperty("ContractId")) {
// @ts-expect-error
delete newContext.ContractId
}
newContext = create(workingContext, (draft) => {
for (const actionSet of Actions as unknown[]) {
// For each action in the action set, apply it individually
for (const actionKey of Object.keys(actionSet)) {
handleActionsOnDraft(
{ [actionKey]: actionSet[actionKey] },
draft,
draft, // Use the draft for reading values so each action sees previous changes
{
originalContext: definition.Context ?? {}
}
)
}
}

// drop the constants
for (const constantKey of constantKeys) {
delete newContext[constantKey]
}
// drop this specific event's value
if (draft.hasOwnProperty("Value")) {
delete draft.Value
}

// drop this specific event's ContractId
if (draft.hasOwnProperty("ContractId")) {
delete draft.ContractId
}

// drop the constants
for (const constantKey of constantKeys) {
delete draft[constantKey]
}
})
}

let state = currentState
Expand Down
Loading