feat: add stripTypes option to return plain objects/arrays#785
Open
podrivo wants to merge 3 commits into
Open
Conversation
…ainObject utility - Added 'stripTypes' boolean option to the game query configuration in gamedig.js and QueryRunner.js. - Implemented 'toPlainObject' function in Results.js to convert query results into plain JavaScript objects, improving serialization and comparison capabilities.
- Documented the new 'stripTypes' boolean option in the query configuration section of README.md, which allows returning results as plain JavaScript objects/arrays for improved serialization and compatibility.
- Added entry for the new `stripTypes` option that allows returning plain JavaScript objects/arrays instead of typed instances, enhancing serialization and compatibility.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #657
Problem
GameDig.query()resolves to a typedResultsinstance whoseplayers/botsarePlayersobjects (anArraysubclass) holdingPlayerinstances. These custom prototypes break common downstream operations:structuredClone(state)/Object.assign({}, state)throw or lose data.TypeError: Class constructor Players cannot be invoked without 'new'.Today consumers must hand-roll a conversion (spreading every nested array) before they can use the result.
Fix
Add an opt-in
stripTypesoption (defaultfalse, so existing behavior is unchanged). When enabled, the final result is recursively converted to plain objects/arrays before being returned.A small recursive helper
toPlainObject()is exported fromlib/Results.js:It's applied at the single success-return point in
QueryRunner.run():stripTypes: falsewas added todefaultOptions, the flag was registered for the CLI (bin/gamedig.js), and it was documented in the README options table.Implementation notes:
Resultshas no existingtoJSON, so nothing to reuse — butPlayers/Playeralready serialize fine viaJSON.stringify. The helper is needed for the non-JSON cases (structuredClone, prototype checks, in-place plain data).Array.from()is used instead of.map()becausePlayers.prototype.map()returns anotherPlayersinstance (Array species), which would defeat the purpose.Buffer/Datevalues, which are alreadystructuredClone-friendly.Examples
CLI:
Node-RED (the motivating case) becomes a one-liner — no manual nested spreading:
Compatibility
stripTypesdefaults tofalse, so the default return value remains the typedResultsinstance.toPlainObjectfromlib/Results.js(additive).Testing
Resultsobject (typedPlayerswithPlayerentries plus a nestedrawobject) and asserted, with the option enabled:Object.getPrototypeOf(result) === Object.prototype(and the same forplayers, each player,raw, and nested objects).playersis a trueArray(not aPlayerssubclass) and entries are notPlayerinstances.JSON.parse(JSON.stringify(result))deep-equals the result.structuredClone(result)succeeds and deep-equals the result.Buffer/Datevalues are preserved rather than flattened.npm run lint:check: changes introduce 0 new lint errors. Note the repo'snpm run lint:checkalready fails on a cleanmaster(identical 31 pre-existing errors before and after this change), because.eslintrc.jsonpinsecmaVersion: 2021while the codebase uses ES2022 class/private fields — unrelated to this PR.