{"_id":"@data-prism/expressions","_rev":"14-7d554f2d028fbde89b0d334941b89eec","name":"@data-prism/expressions","dist-tags":{"latest":"0.0.16"},"versions":{"0.0.2":{"name":"@data-prism/expressions","version":"0.0.2","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.2","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"ff0176e30c7e6aa96eb461f581e49ec63f23cc06","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.2.tgz","fileCount":39,"integrity":"sha512-1GT+2sqm4vy1TzRI+NfetrG8miztM8Q4ZMEeyQZvA74n2+Llf3Pzakx57mOUEmp6QO+NFHIh0xr2ULVJZZZd2Q==","signatures":[{"sig":"MEQCIGeEGDIYVQa1REz8IQ6dR5QZdBVnz1PRglAggjAZcqAaAiB8/B9vBAaDKpzeRQPQZDnIuOuqbH+xuayXynL+NWmjgw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":187118},"main":"./dist/src/expression.js","type":"module","types":"./dist/src/expression.d.ts","exports":{".":"./dist/src/expression.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"1d819fff8072ab9b07a042e7654834397bac30a7","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.5.0","description":"## Uses","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.34.0","vitest":"^0.28.5","prettier":"^2.8.4","typescript":"^5.0.0-beta","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.6.0","eslint-config-standard":"^17.0.0","@typescript-eslint/parser":"^5.52.0","@typescript-eslint/eslint-plugin":"^5.52.0"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.2_1685723759769_0.06506989812525954","host":"s3://npm-registry-packages"}},"0.0.4":{"name":"@data-prism/expressions","version":"0.0.4","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.4","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"8dbce1756b7071c1f73a3540f83e8f906b4b02df","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.4.tgz","fileCount":40,"integrity":"sha512-kDOQhm3GQomLuf3a3anJUV8tIU5bWGuWI9tHtAaT0ZNXUTRHkVhjAXmjzqdZqN5/5esSgnXflTgwMInCdc4iiQ==","signatures":[{"sig":"MEYCIQDpeyQYVIhjM/naz0JC1OsXrBH0dF5iOCmipiX671NFUwIhALh1dCPPYd+58XKoq5jjNYPyMfH6XFmoYSZ/EodQ+UBS","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109362},"main":"./dist/src/expressions.js","type":"module","types":"./dist/src/expressions.d.ts","exports":{".":"./dist/src/expressions.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"def46bbdd2268ecc01a86c4497c5997551119463","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.5.0","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.4_1691079704346_0.25194951441189706","host":"s3://npm-registry-packages"}},"0.0.5":{"name":"@data-prism/expressions","version":"0.0.5","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.5","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"a6d44da9db0f86e2e2307e010719dbd28fc7ceda","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.5.tgz","fileCount":40,"integrity":"sha512-zhLJP9GBSQuDfh5FxLfG/VfJTN7ItfxLGJfC7GEit+iDYzylqZ7sbf9aSbkhvchmkfaIUBei8Y0zqyE2nplrzg==","signatures":[{"sig":"MEYCIQDDYYRsr2qoqFIvlJSa6d9l9VlCu+cA2vqCNgEVUuXUkAIhAInz+8AO2UsoKa/i+5kt22YD35LVH83s4V4njfRpjdFx","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110134},"main":"./dist/src/expressions.js","type":"module","types":"./dist/src/expressions.d.ts","exports":{".":"./dist/src/expressions.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"ad669142bec758bb374a398aa2165655e38c9056","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.5.0","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.5_1691169766528_0.7864630656041789","host":"s3://npm-registry-packages"}},"0.0.6":{"name":"@data-prism/expressions","version":"0.0.6","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.6","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"c625e006f326d78b39fb260a1ce9bae1817cc858","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.6.tgz","fileCount":39,"integrity":"sha512-C3BBc8Zun0e2qyqPZHZriWbElVIoI92Cf5jnYhDrhyimFLSz7a4Yu+aejqfxUQIcuK9lWH6yxTHnM0JA+jbDcA==","signatures":[{"sig":"MEUCIQCZlp+ZO7kjwnzhnWIHkEZMDwDpHV6N6NUAV/+RQG9JGAIgXb86aEuM3P2Lb6BpiTu9sHUdZvKxG+0jbY7QtRiaXQc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":111350},"main":"./dist/src/expressions.js","type":"module","types":"./dist/src/expressions.d.ts","exports":{".":"./dist/src/expressions.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"b5d3b98aaedc640be725270910c6c4350fb9e25e","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.5.0","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.6_1691184991175_0.7048788639877912","host":"s3://npm-registry-packages"}},"0.0.7":{"name":"@data-prism/expressions","version":"0.0.7","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.7","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"54aa3f882238032b2a54227ee4c09bba20dd2f49","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.7.tgz","fileCount":43,"integrity":"sha512-HgzA4ceikV1vWhnXt7oAWacaL39rMeAw63mnBPOSPbX00yLxcVSVGAD1+oTpgDqRJMmZfG+nj7Se44SMR177PQ==","signatures":[{"sig":"MEUCIQCYJiTiqJSnr9al+EyjRM1+EPQWc/xSx0pHMnR1xkXt2gIgAx7VEyz8Gj+Qg5/ux+6kJ+i3pi8JJeVjQfb6sUMJIZ8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":117413},"main":"./dist/src/expressions.js","type":"module","types":"./dist/src/expressions.d.ts","exports":{".":"./dist/src/expressions.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"6ff659eee613b33b17fe88e5f6462f7c9fc6f5ae","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.5.0","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.7_1692204636749_0.9103811472217789","host":"s3://npm-registry-packages"}},"0.0.8":{"name":"@data-prism/expressions","version":"0.0.8","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.8","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"05dab24c3b1c2eb77e9533f2fc36411316609e52","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.8.tgz","fileCount":43,"integrity":"sha512-zSVptyCSNOtYqO1SIuVxBh3PlsNOrkwZFvFXWOpxv0p2GEignoMeq/gwEgj3K25fcHTVnTogzOluPwwmxDEh+A==","signatures":[{"sig":"MEUCIBbKbvKva9KQ26mgijce1n3PxfnwnBr4HsbZSfx73uYuAiEA8kEECFAKvX7rVRExE7zMcOnFsVlqEiBT7XyfCwmeo2Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":117404},"main":"./dist/src/expressions.js","type":"module","types":"./dist/src/expressions.d.ts","exports":{".":"./dist/src/expressions.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"9bc75c8c242017401d97e9c82fe57a5a7bce13d3","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.8.1","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.8_1694020510512_0.6396957108173169","host":"s3://npm-registry-packages"}},"0.0.9":{"name":"@data-prism/expressions","version":"0.0.9","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.9","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"92c99d9c8b9ae3886267e912158dc7bffd1c7ceb","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.9.tgz","fileCount":43,"integrity":"sha512-4K1L83/DGCn2rxiTYvLN8IS/SP+2oWj1R1Dbrur5G0nPoVnGp96hD5jKFZXlLSRpX3CgHZNM2UA+VtgNFBFI/g==","signatures":[{"sig":"MEUCIDYCulUml44Y3/SiPZIQIQ+wWuUa5kz00Yw5Q5R54WEAAiEAoEN0MIU0QjlG8p0hM5o4lPSckEyvKABx00VaGTbg9qI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":117342},"main":"./dist/src/expressions.js","type":"module","types":"./dist/src/expressions.d.ts","exports":{".":"./dist/src/expressions.js","./*":{"import":"./src/*.js","require":"./dist/*.js"}},"gitHead":"fa255ef4e06d35f40c2de0dcea8258a6e448f327","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.8.1","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.9_1694196291337_0.7546014741696552","host":"s3://npm-registry-packages"}},"0.0.10":{"name":"@data-prism/expressions","version":"0.0.10","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.10","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"8383d91855708a80ec88d4058c310730287b6d33","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.10.tgz","fileCount":54,"integrity":"sha512-eSteu57fiL7A+zbTOaOeHd4E3Q3DVnCq4KQMgwfPEXxyEirGH3LlVhVR8rN547wdq8YD9VefqUUI0ZW3XjxX3Q==","signatures":[{"sig":"MEUCIQCANht1R+fN2o4zkLiXAlsZrfEflOlvMx+yQvj60me5XwIgXDYELXdRPJ8GhbexnZ+DIzwOXNfTfYF22qXfhzpT9E8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":289169},"main":"./build/cjs/src/index.js","type":"module","types":"./build/cjs/src/index.d.ts","module":"./build/mjs/src/index.js","exports":{"import":"./build/esm/src/index.js","require":"./build/cjs/src/index.js"},"gitHead":"0fdff3d84050afbd09cb406aa6ecd60c0f08d077","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"9.8.1","directories":{},"_nodeVersion":"18.15.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.54.0","vitest":"^0.34.6","prettier":"^3.1.0","typescript":"^5.3.2","@types/lodash-es":"^4.17.12","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^9.0.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^6.13.0","@typescript-eslint/eslint-plugin":"^6.13.0"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.10_1701192756341_0.4967456047198595","host":"s3://npm-registry-packages"}},"0.0.11":{"name":"@data-prism/expressions","version":"0.0.11","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.11","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"36af6fa6b768adb1ab9a9ee7e756d584db176a9d","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.11.tgz","fileCount":51,"integrity":"sha512-4X50ii1qvW+4EWVztTmVKgbMyNypiMMkfbvBNwKZ1xMEDtVKimKP9RcpMUjGIL22lUcgteWlJcNQ4Q8E2q2KWg==","signatures":[{"sig":"MEYCIQCd4iATkVZbaY1PNIW5fTsurtCR9f0g4e3YJpXHpV5gSgIhAMFH3EvNBxPXe+oZGbWAi9k5TblUgmzCTmTy9rAQEPrV","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":225922},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"2f08eb97e865f94a509fe0d01404a8890fbbe738","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"10.5.2","directories":{},"_nodeVersion":"20.13.1","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.11_1726954211317_0.5239474943718156","host":"s3://npm-registry-packages"}},"0.0.12":{"name":"@data-prism/expressions","version":"0.0.12","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.12","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"cbee6dbfb7b623640b08d5bdb12a8de8e13df825","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.12.tgz","fileCount":51,"integrity":"sha512-XPC8vBOOYkfeEGsqhEYFKQb4HoS71JfUnTOFlJ+iiJ2k0zrWw05O+c7v80WrJuAQAjzV/Rw8qyq7H3GzQNUK3w==","signatures":[{"sig":"MEUCIAXRzKHKchsfQf88CcHa/c5VeXBRFCZdjH8tPuJw6WfYAiEA0jiGv37TVIsgzz9JQRSo47AUXwLObHs0ntxmxE2zaAs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":228699},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"8b123daf9e68da720a271b2df56b711227634a9c","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"10.5.2","directories":{},"_nodeVersion":"20.13.1","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.41.0","vitest":"^0.31.4","prettier":"^2.8.8","typescript":"^5.1.3","@types/lodash-es":"^4.17.7","typescript-eslint":"^0.0.1-alpha.0","eslint-config-prettier":"^8.8.0","eslint-config-standard":"^17.1.0","@typescript-eslint/parser":"^5.59.8","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.12_1727049546548_0.059116878596745526","host":"s3://npm-registry-packages"}},"0.0.13":{"name":"@data-prism/expressions","version":"0.0.13","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.13","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"075f07b22cbf12991e0488a6537070e7722ad374","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.13.tgz","fileCount":52,"integrity":"sha512-4BxtQErUoaljbcdX1MAT84mhxkYVg6PxeYB4tcWVq8lgRTM+blRqnYbLMz4IYavTdHCLDIzchGkgGvZv2drJ+w==","signatures":[{"sig":"MEUCIQCnUTRjj14wk9z2a5fjm0Np++3EWdmuppX3A0ImN8J2JwIgcBHfY1MWDS/dlaIPuU4i/qGz9bSFWoHFJNQEh8WJ0Rs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":224936},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"2363e0173d21abefd58ac5b32420886f582c3b72","private":false,"scripts":{"test":"NODE_ENV=test vitest","build":"NODE_OPTIONS='--max-old-space-size=8192' tsc -p ./tsconfig.json"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"11.4.2","directories":{},"_nodeVersion":"23.6.0","dependencies":{"vite":"7.0.6","lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.1.3","@types/lodash-es":"^4.17.7"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.13_1754334326915_0.2368749492533","host":"s3://npm-registry-packages-npm-production"}},"0.0.14":{"name":"@data-prism/expressions","version":"0.0.14","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.14","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"eee56f2d6803c0d21f27c4bad32a0497bf95d527","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.14.tgz","fileCount":5,"integrity":"sha512-zg7P/JPE6ETYg/rt7sfce9ILrGODmQ6bHHdYTC1GWlgF2qA31ou9h/PijlKpgYspzuLC4MrakgcbI9RQozCObA==","signatures":[{"sig":"MEYCIQCHS+mRmEwHtvdZggpSTrQblGWqXz6zbDR28aKGckrCqgIhAOpWO6xT5nZWqMp0ocUX6ABzuXTasbdOJTErigu1NbUc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64322},"main":"./dist/index.cjs.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"}},"gitHead":"b996596e1fad67a85585166ba1344dc8e8bba75e","private":false,"scripts":{"lint":"eslint src/ test/","test":"NODE_ENV=test vitest run --coverage","build":"npm run clean && rollup -c && cp index.d.ts dist/","clean":"rm -rf dist","test:watch":"vitest","prepublishOnly":"npm run lint && npm run test"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"11.4.2","description":"A JavaScript expression engine for enhancing Data Prism queries with computed values and conditional logic. Data Prism Expressions provides a JSON-based syntax for creating dynamic where clauses and calculated select fields, extending the core querying ca","directories":{},"sideEffects":false,"_nodeVersion":"23.6.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.28.1","vitest":"^3.0.4","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^3.2.4","@rollup/plugin-commonjs":"^28.0.1","@vitest/coverage-istanbul":"^3.0.4","@rollup/plugin-node-resolve":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.14_1755634018754_0.2447779212486696","host":"s3://npm-registry-packages-npm-production"}},"0.0.15":{"name":"@data-prism/expressions","version":"0.0.15","keywords":[],"author":{"name":"Jake Sower"},"_id":"@data-prism/expressions@0.0.15","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"dist":{"shasum":"4c49668f64f167755fe0bb2ebd532fe6313f3782","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.15.tgz","fileCount":5,"integrity":"sha512-YF8tZmy+yWO9888mqIjBb7/qNDyTdqBjuRWPLjST2e8dMYTee4VNQlCvLodQKROvpAh03TBO/qeToBufSfbffA==","signatures":[{"sig":"MEYCIQD+I5SeASBTRfpbQ1+u9UgSocRyUJduPCS5HzphGzIYygIhAKsvZPg7wYrm991PifXQWYV3+f+6F8pKgi2htR5jDyxe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60863},"main":"./dist/index.cjs.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"}},"gitHead":"e3e771cd06ec07ad9d1189689e7fcaaf5fdc6126","private":false,"scripts":{"lint":"eslint src/ test/","test":"NODE_ENV=test vitest run --coverage","build":"npm run clean && rollup -c && cp index.d.ts dist/","clean":"rm -rf dist","test:watch":"vitest","prepublishOnly":"npm run lint && npm run test"},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"_npmVersion":"11.4.2","description":"A JavaScript expression engine for enhancing Data Prism queries with computed values and conditional logic. Data Prism Expressions provides a JSON-based syntax for creating dynamic where clauses and calculated select fields, extending the core querying ca","directories":{},"sideEffects":false,"_nodeVersion":"23.6.0","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.28.1","vitest":"^3.0.4","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^3.2.4","@rollup/plugin-commonjs":"^28.0.1","@vitest/coverage-istanbul":"^3.0.4","@rollup/plugin-node-resolve":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/expressions_0.0.15_1755884030531_0.9820333976921631","host":"s3://npm-registry-packages-npm-production"}},"0.0.16":{"name":"@data-prism/expressions","version":"0.0.16","type":"module","main":"./dist/index.cjs.js","module":"./dist/index.esm.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"}},"scripts":{"build":"npm run clean && rollup -c && cp index.d.ts dist/","clean":"rm -rf dist","format:check":"prettier --check \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"","format:fix":"prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"","lint":"eslint src/ test/","lint:fix":"eslint --fix src/ test/","prepublishOnly":"npm run lint && npm run test","test":"NODE_ENV=test vitest run --coverage","test:watch":"vitest"},"keywords":[],"author":{"name":"Jake Sower"},"devDependencies":{"@rollup/plugin-commonjs":"^28.0.1","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.0","@vitest/coverage-istanbul":"^3.0.4","@vitest/coverage-v8":"^3.2.4","rollup":"^4.28.1","vitest":"^3.0.4"},"publishConfig":{"access":"public"},"private":false,"sideEffects":false,"dependencies":{"lodash-es":"^4.17.21"},"_id":"@data-prism/expressions@0.0.16","gitHead":"498ea1b116acec3666985682bb82a7fdd0b144ab","description":"> **⚠️ DEPRECATED**: This package has been merged into `@data-prism/core` for better integration and simpler dependency management. Please migrate to `@data-prism/core` which includes all expression functionality. This package will receive no further upda","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-fQDLIuERcaZ4zDkHx0zkGIO+89wXsdmt84/AuHwCbu/oVggBF5o5WGthxLCr1SBxfOV3yONE/JQyW9Tp6rP/qw==","shasum":"2070cca2f95ad9de5e639f5d9e77dcd12faea96e","tarball":"https://registry.npmjs.org/@data-prism/expressions/-/expressions-0.0.16.tgz","fileCount":5,"unpackedSize":68234,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIF274lIjBEWMX7uZtpVqYgocx0Vr9lPSF4gE39SBhaZvAiA3uwujNWHrR6IfB4kxBFickg7bd9hllcasKCRr/+0ooA=="}]},"_npmUser":{"name":"blossomlib","email":"kind.salt4683@fastmail.com"},"directories":{},"maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/expressions_0.0.16_1756139652103_0.3487653917236464"},"_hasShrinkwrap":false}},"time":{"created":"2023-06-02T16:35:59.710Z","modified":"2025-08-25T16:34:12.464Z","0.0.2":"2023-06-02T16:35:59.990Z","0.0.4":"2023-08-03T16:21:44.561Z","0.0.5":"2023-08-04T17:22:46.703Z","0.0.6":"2023-08-04T21:36:31.406Z","0.0.7":"2023-08-16T16:50:36.955Z","0.0.8":"2023-09-06T17:15:10.793Z","0.0.9":"2023-09-08T18:04:51.510Z","0.0.10":"2023-11-28T17:32:36.532Z","0.0.11":"2024-09-21T21:30:11.545Z","0.0.12":"2024-09-22T23:59:06.773Z","0.0.13":"2025-08-04T19:05:27.172Z","0.0.14":"2025-08-19T20:06:58.951Z","0.0.15":"2025-08-22T17:33:50.713Z","0.0.16":"2025-08-25T16:34:12.297Z"},"author":{"name":"Jake Sower"},"keywords":[],"description":"> **⚠️ DEPRECATED**: This package has been merged into `@data-prism/core` for better integration and simpler dependency management. Please migrate to `@data-prism/core` which includes all expression functionality. This package will receive no further upda","maintainers":[{"name":"blossomlib","email":"kind.salt4683@fastmail.com"}],"readme":"# Data Prism Expressions\n\n> **⚠️ DEPRECATED**: This package has been merged into `@data-prism/core` for better integration and simpler dependency management. Please migrate to `@data-prism/core` which includes all expression functionality. This package will receive no further updates.\n\nA JavaScript expression engine for enhancing Data Prism queries with computed values and conditional logic. Data Prism Expressions provides a JSON-based syntax for creating dynamic where clauses and calculated select fields, extending the core querying capabilities with lightweight programmatic logic.\n\nIt is suitable for more general applications that call for simple logic that needs to be written as JSON. It is inspired by the Lisp concept of code being data.\n\n## Migration\n\n**Old:**\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/expressions\";\n```\n\n**New:**\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/core\";\n```\n\nAll expression functionality remains identical - only the import path has changed.\n\n## Overview\n\nData Prism Expressions is built around several key principles:\n\n- **Query enhancement**: Adds computed fields and conditional logic to Data Prism queries\n- **Extensible**: Built for users to extend with custom expressions and operations\n- **Lightweight**: Focuses on the most common expressions needed in data queries\n- **JSON-native**: Uses JSON objects that can be serialized and stored\n\n## Installation\n\n```bash\n# Deprecated - use @data-prism/core instead\nnpm install @data-prism/expressions\n\n# Recommended\nnpm install @data-prism/core\n```\n\n## Core Concepts\n\n### Expressions\n\nExpressions are JSON objects that describe computations to be performed on data. Each expression has a single key that identifies the operation (prefixed with `$`) and a value that provides the parameters:\n\n```json\n// Simple comparison\n{ \"$gt\": 18 }  // arg > 18\n\n// Logical operations\n{ \"$and\": [\n  { \"$gt\": 80 },\n  { \"$lt\": 5 }\n]}\n\n// Conditional logic\n{ \"$if\": {\n  \"if\": { \"$eq\": \"active\" },\n  \"then\": { \"$get\": \"fullName\" },\n  \"else\": \"Inactive User\"\n}}\n```\n\n### Expression Engine\n\nThe expression engine holds the expressions definitions and allows for them to be used in a few ways:\n\n#### `apply`\n\nApplies the expression like a function to a value.\n\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/expressions\";\n\nconst expression = { $gt: 21 };\nconst data = 25;\n\nconst result = defaultExpressionEngine.apply(expression, value);\n// Returns: true\n```\n\n#### `evaluate`\n\nTakes an expression in its evaluable form and evaluates it, returning a value wholly determined by the expression itself. It is not applied to anything, but is fully self-contained.\n\n```javascript\n// Evaluate expressions without input data (for static expressions)\nconst staticResult = defaultExpressionEngine.evaluate({ $sum: [1, 2, 3] });\n// Returns: 6\n```\n\n#### `normalizeWhereClause`\n\nTransforms an expression from Data Prism's user-focused form to an equivalent expression that's more suitable for consumption by stores as they execute the `where` clause of a query. It lives in this repository for extensibility purposes, as expressions can define their own `normalizeWhere` functions to handle complex behavior.\n\n## API Reference\n\n### Core Functions\n\n#### `createExpressionEngine(definitions)`\n\nCreates a custom expression engine with additional operation definitions.\n\n**Parameters:**\n\n- `definitions` (object) - Custom operation definitions to add to the engine\n\n**Returns:** ExpressionEngine with core + custom operations\n\n```javascript\nimport { createExpressionEngine } from \"@data-prism/expressions\";\n\nconst customEngine = createExpressionEngine({\n\t$customOp: {\n\t\tapply: (params, data) => {\n\t\t\t// Custom operation logic\n\t\t\treturn params + data;\n\t\t},\n\t},\n});\n```\n\n#### `defaultExpressionEngine`\n\nPre-configured expression engine with all built-in operations.\n\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/expressions\";\n\nconst result = defaultExpressionEngine.apply(expression, data);\n```\n\n### ExpressionEngine Methods\n\n#### `apply(expression, data)`\n\nEvaluates an expression against input data.\n\n**Parameters:**\n\n- `expression` (Expression) - The expression to evaluate\n- `data` (any) - The data context for evaluation\n\n**Returns:** Result of the expression evaluation\n\n```javascript\nconst expression = { $sum: [10, 20] };\nconst data = [1, 2, 3, 4];\n\nconst result = engine.apply(expression, data);\n// Returns: 10 (sum of [10, 20])\n```\n\n#### `evaluate(expression)`\n\nEvaluates an expression without input data (for static expressions).\n\n**Parameters:**\n\n- `expression` (Expression) - The expression to evaluate\n\n**Returns:** Static result of the expression\n\n```javascript\nconst expression = { $sum: [10, 20] };\nconst result = engine.evaluate(expression);\n// Returns: 30\n```\n\n#### `isExpression(value)`\n\nTests whether a value is a valid expression.\n\n**Parameters:**\n\n- `value` (any) - The value to test\n\n**Returns:** Boolean indicating if the value is an expression\n\n```javascript\nconst isExpr1 = engine.isExpression({ $get: \"name\" }); // true\nconst isExpr2 = engine.isExpression({ name: \"Juan\" }); // false\n```\n\n#### `normalizeWhereClause(where)`\n\nNormalizes a user-friendly where clause into executable expressions for query processing.\n\n**Parameters:**\n\n- `where` (object) - The where clause to normalize\n\n**Returns:** Normalized expression suitable for query execution\n\n```javascript\nconst where = { name: \"Juan\", age: { $gt: 18 } };\nconst normalized = engine.normalizeWhereClause(where);\n// Returns: { $and: [\n//   { $pipe: [{ $get: \"name\" }, { $eq: \"Juan\" }] },\n//   { $pipe: [{ $get: \"age\" }, { $gt: 18 }] }\n// ] }\n```\n\n## Built-in Operations\n\n### Core Operations\n\n#### `$apply`\n\nApplies the parameters directly (identity for parameters).\n\n```json\n{ \"$apply\": [1, 2, 3] } // Returns [1, 2, 3]\n```\n\n#### `$compose`\n\nComposes multiple expressions together using mathematical composition order (right-to-left). The expressions are applied in the order `f(g(h(x)))` where `[f, g, h]` means `f` applied to the result of `g` applied to the result of `h` applied to `x`.\n\n```json\n{\n\t\"$compose\": [\n\t\t{ \"$map\": { \"$get\": \"name\" } }, // f: map to names\n\t\t{ \"$filter\": { \"$gt\": 18 } }, // g: filter adults\n\t\t{ \"$get\": \"users\" } // h: get users\n\t]\n}\n```\n\n#### `$debug`\n\nEvaluates an expression, logs the result to console, and returns the result (useful for debugging intermediate values in expression chains).\n\n```json\n{ \"$debug\": { \"$get\": \"name\" } } // Logs the value of data.name, returns data.name\n{ \"$debug\": { \"$sum\": [1, 2, 3] } } // Logs 6, returns 6\n```\n\n#### `$echo`\n\nReturns the input data unchanged (identity function).\n\n```json\n{ \"$echo\": null } // Returns the entire input data object\n```\n\n#### `$ensurePath`\n\nValidates that a path exists in the data, throwing an error if not found.\n\n```json\n{ \"$ensurePath\": \"user.profile.email\" } // Throws if path doesn't exist\n```\n\n#### `$get`\n\nRetrieves a value from the data object using lodash-style path notation.\n\n```json\n{ \"$get\": \"name\" }          // Gets data.name\n{ \"$get\": \"user.age\" }      // Gets data.user.age (nested path)\n```\n\n#### `$isDefined`\n\nTests whether the input data is defined (not undefined).\n\n```json\n{ \"$isDefined\": null } // Returns true if data !== undefined\n```\n\n#### `$literal`\n\nReturns a literal value (useful when you need to pass a value that might be confused with an expression).\n\n```json\n{ \"$literal\": { \"$get\": \"not-an-expression\" } }\n```\n\n#### `$pipe`\n\nPipes data through multiple expressions using pipeline order (left-to-right). The expressions are applied in the order `h(g(f(x)))` where `[h, g, f]` means `f` applied to `x`, then `g` applied to that result, then `h` applied to that result.\n\n```json\n{\n\t\"$pipe\": [\n\t\t{ \"$get\": \"users\" }, // h: get users\n\t\t{ \"$filter\": { \"$gt\": 18 } }, // g: filter adults\n\t\t{ \"$map\": { \"$get\": \"name\" } } // f: map to names\n\t]\n}\n```\n\n**Note**: `$pipe` is often more intuitive as it matches the natural reading order, while `$compose` follows mathematical function composition conventions.\n\n### Conditional Operations\n\n#### `$case`\n\nSwitch-like expression that matches a value against multiple cases and returns the corresponding result.\n\n```json\n{\n\t\"$case\": {\n\t\t\"value\": { \"$get\": \"activity\" },\n\t\t\"cases\": [\n\t\t\t{ \"when\": \"playing\", \"then\": \"Child is playing\" },\n\t\t\t{ \"when\": \"napping\", \"then\": \"Child is napping\" },\n\t\t\t{ \"when\": \"eating\", \"then\": \"Child is eating\" }\n\t\t],\n\t\t\"default\": \"Unknown activity\"\n\t}\n}\n```\n\nThe `$case` expression evaluates the `value` once and compares it against each `when` clause. When a match is found, it returns the corresponding `then` value. If no match is found, it returns the `default` value.\n\n**When clauses support two formats:**\n\n- **Simple equality**: `{ \"when\": \"value\" }` - matches if the value equals \"value\"\n- **Complex expressions**: `{ \"when\": { \"$eq\": \"value\" } }` - evaluates the expression with the value as input\n\nAll parts (`value`, `when`, `then`, `default`) can be expressions or literal values.\n\n#### `$if`\n\nConditional expression that evaluates different branches based on a condition.\n\n```json\n{\n\t\"$if\": {\n\t\t\"if\": { \"$gte\": 18 },\n\t\t\"then\": \"Adult\",\n\t\t\"else\": \"Minor\"\n\t}\n}\n```\n\n### Logical Operations\n\n#### `$and`\n\nLogical AND operation - all expressions must be truthy.\n\n```json\n{ \"$and\": [{ \"$gt\": 18 }, { \"$eq\": \"active\" }] }\n```\n\n#### `$not`\n\nLogical NOT operation - inverts the truthiness of an expression.\n\n```json\n{ \"$not\": { \"$eq\": true } }\n```\n\n#### `$or`\n\nLogical OR operation - at least one expression must be truthy.\n\n```json\n{ \"$or\": [{ \"$eq\": \"admin\" }, { \"$eq\": \"moderator\" }] }\n```\n\n### Comparison Operations\n\nAll comparison operations use mathematical abbreviations for consistency and brevity.\n\n#### `$eq`\n\nEquality comparison using deep equality.\n\n```json\n{ \"$eq\": \"published\" } // data === \"published\"\n```\n\n#### `$gt`\n\nGreater than comparison.\n\n```json\n{ \"$gt\": 90 } // data > 90\n```\n\n#### `$gte`\n\nGreater than or equal comparison.\n\n```json\n{ \"$gte\": 18 } // data >= 18\n```\n\n#### `$in`\n\nArray membership test (in).\n\n```json\n{ \"$in\": [\"tech\", \"science\", \"math\"] } // data is in array\n```\n\n#### `$lt`\n\nLess than comparison.\n\n```json\n{ \"$lt\": 100 } // data < 100\n```\n\n#### `$lte`\n\nLess than or equal comparison.\n\n```json\n{ \"$lte\": 3 } // data <= 3\n```\n\n#### `$ne`\n\nInequality comparison using deep equality.\n\n```json\n{ \"$ne\": \"draft\" } // data !== \"draft\"\n```\n\n#### `$nin`\n\nArray membership test (not in).\n\n```json\n{ \"$nin\": [\"deleted\", \"archived\"] } // data is not in array\n```\n\n### Aggregative Operations\n\n#### `$count`\n\nCount of items in an array.\n\n```json\n{ \"$count\": [1, 2, 3, 4] } // Returns 4\n```\n\n#### `$max`\n\nMaximum of array values.\n\n```json\n{ \"$max\": [1, 5, 3, 9] } // Returns 9\n```\n\n#### `$mean`\n\nArithmetic mean (average) of array values.\n\n```json\n{ \"$mean\": [1, 2, 3, 4, 5] } // Returns 3\n```\n\nReturns `undefined` for empty arrays.\n\n#### `$median`\n\nMedian (middle value) of array values.\n\n```json\n{ \"$median\": [1, 2, 3, 4, 5] } // Returns 3\n{ \"$median\": [1, 2, 3, 4] }    // Returns 2.5 (average of middle two)\n```\n\nReturns `undefined` for empty arrays.\n\n#### `$min`\n\nMinimum of array values.\n\n```json\n{ \"$min\": [1, 5, 3, 9] } // Returns 1\n```\n\n#### `$mode`\n\nMode (most frequent value) of array values.\n\n```json\n{ \"$mode\": [1, 2, 2, 3, 4] }    // Returns 2 (single mode)\n{ \"$mode\": [1, 1, 2, 2, 3] }    // Returns [1, 2] (multiple modes)\n{ \"$mode\": [1, 2, 3, 4, 5] }    // Returns undefined (no mode)\n```\n\nReturns the single mode value, array of multiple modes, or `undefined` if no mode exists.\n\n#### `$quantile`\n\nCalculates quantiles (percentiles, quartiles, etc.) of array values.\n\n```json\n// Quartiles (4-quantiles)\n{ \"$quantile\": { \"values\": [1,2,3,4,5,6,7,8,9,10], \"k\": 1, \"n\": 4 } } // Q1\n{ \"$quantile\": { \"values\": [1,2,3,4,5,6,7,8,9,10], \"k\": 2, \"n\": 4 } } // Q2 (median)\n{ \"$quantile\": { \"values\": [1,2,3,4,5,6,7,8,9,10], \"k\": 3, \"n\": 4 } } // Q3\n\n// Percentiles (100-quantiles)\n{ \"$quantile\": { \"values\": [1,2,3,4,5,6,7,8,9,10], \"k\": 50, \"n\": 100 } } // 50th percentile\n{ \"$quantile\": { \"values\": [1,2,3,4,5,6,7,8,9,10], \"k\": 90, \"n\": 100 } } // 90th percentile\n```\n\n**Parameters:**\n\n- `values`: Array of numeric values\n- `k`: The k-th quantile to calculate (0 ≤ k ≤ n)\n- `n`: The total number of quantiles (e.g., 4 for quartiles, 100 for percentiles)\n\nReturns `undefined` for empty arrays. Uses linear interpolation for non-integer indices.\n\n#### `$sum`\n\nSum of array values.\n\n```json\n{ \"$sum\": [1, 2, 3, 4] } // Returns 10\n```\n\n### Iterative Operations\n\n#### `$all`\n\nTests if all elements in an array satisfy a predicate (similar to Array.every).\n\n```json\n{ \"$all\": { \"$gt\": 0 } } // Returns true if all items > 0\n```\n\n#### `$any`\n\nTests if any element in an array satisfies a predicate (similar to Array.some).\n\n```json\n{ \"$any\": { \"$gt\": 50 } } // Returns true if any item > 50\n```\n\n#### `$concat`\n\nConcatenates two arrays together.\n\n```json\n{ \"$concat\": [4, 5] } // With input [1, 2, 3], returns [1, 2, 3, 4, 5]\n```\n\n#### `$filter`\n\nFilter array items based on a condition.\n\n```json\n{ \"$filter\": { \"$gt\": 50 } } // Filters array, keeping items > 50\n```\n\n#### `$find`\n\nReturns the first element in an array that satisfies a predicate, or undefined if none found.\n\n```json\n{ \"$find\": { \"$eq\": \"target\" } } // Returns first item === \"target\"\n```\n\n#### `$flatMap`\n\nTransform and flatten array items.\n\n```json\n{ \"$flatMap\": { \"$get\": \"products\" } } // Maps and flattens results\n```\n\n#### `$join`\n\nJoins array elements into a string with a separator.\n\n```json\n{ \"$join\": \", \" } // With input [1, 2, 3], returns \"1, 2, 3\"\n{ \"$join\": \"\" }   // With input [\"a\", \"b\", \"c\"], returns \"abc\"\n```\n\n#### `$map`\n\nTransform each item in an array.\n\n```json\n{ \"$map\": { \"$get\": \"name\" } } // Maps over array, getting \"name\" from each item\n```\n\n#### `$reverse`\n\nReturns a new array with elements in reverse order.\n\n```json\n{ \"$reverse\": {} } // With input [1, 2, 3], returns [3, 2, 1]\n```\n\n### Generative Operations\n\n#### `$random`\n\nGenerates a random number with optional range and precision control.\n\n```json\n{ \"$random\": {} }                                          // 0 to 1 (default)\n{ \"$random\": { \"min\": 10, \"max\": 20 } }                   // 10 to 20 range\n{ \"$random\": { \"min\": 0, \"max\": 1, \"precision\": 2 } }     // 2 decimal places (0.XX)\n{ \"$random\": { \"min\": 0, \"max\": 100, \"precision\": 0 } }   // Integers (0 decimal places)\n{ \"$random\": { \"min\": 0, \"max\": 1000, \"precision\": -1 } } // Round to nearest 10\n```\n\n**Parameters:**\n\n- `min` (default: 0): Minimum value (inclusive)\n- `max` (default: 1): Maximum value (exclusive)\n- `precision` (default: null): Decimal places for positive values, or power of 10 for negative values\n  - `precision: 2` → 2 decimal places (0.01 precision)\n  - `precision: 0` → integers (1.0 precision)\n  - `precision: -1` → round to nearest 10\n  - `precision: null` → no rounding (full precision)\n\n#### `$uuid`\n\nGenerates a unique UUID v4 string.\n\n```json\n{ \"$uuid\": null } // Returns UUID like \"f47ac10b-58cc-4372-a567-0e02b2c3d479\"\n```\n\nThe operand is ignored - this expression always generates a new UUID.\n\n### Temporal Operations\n\n#### `$nowLocal`\n\nReturns the current date and time as a local RFC3339 string with timezone offset.\n\n```json\n{ \"$nowLocal\": null } // Returns \"2024-01-01T05:00:00.000-07:00\"\n```\n\nThe operand is ignored - this expression returns the current local time with timezone information in RFC3339 format.\n\n#### `$nowUTC`\n\nReturns the current date and time as a UTC RFC3339 string.\n\n```json\n{ \"$nowUTC\": null } // Returns \"2024-01-01T12:00:00.000Z\"\n```\n\nThe operand is ignored - this expression always returns the current UTC time in RFC3339 format.\n\n#### `$timestamp`\n\nReturns the current timestamp as a number (milliseconds since Unix epoch).\n\n```json\n{ \"$timestamp\": null } // Returns current timestamp like 1704067200000\n```\n\nThe operand is ignored - this expression always returns the current timestamp when evaluated.\n\n## Examples\n\n### Basic Usage\n\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/expressions\";\n\nconst data = {\n\tuser: { name: \"Fatoumata\", age: 30 },\n\torders: [\n\t\t{ id: 1, amount: 50 },\n\t\t{ id: 2, amount: 75 },\n\t\t{ id: 3, amount: 120 },\n\t],\n};\n\n// Check if user is adult\nconst isAdult = defaultExpressionEngine.apply({ $gte: 18 }, data.user.age);\n// Returns: true\n\n// Get user name\nconst userName = defaultExpressionEngine.apply({ $get: \"name\" }, data.user);\n// Returns: \"Fatoumata\"\n\n// Calculate total order amount\nconst orderAmounts = data.orders.map((order) => order.amount);\nconst totalAmount = defaultExpressionEngine.apply({ $sum: orderAmounts }, null);\n// Returns: 245\n\n// Calculate average order amount\nconst avgAmount = defaultExpressionEngine.apply({ $mean: orderAmounts }, null);\n// Returns: 81.67\n\n// Get median order amount\nconst medianAmount = defaultExpressionEngine.apply(\n\t{ $median: orderAmounts },\n\tnull,\n);\n// Returns: 75\n\n// Calculate 75th percentile of order amounts\nconst p75 = defaultExpressionEngine.apply(\n\t{\n\t\t$quantile: { values: orderAmounts, k: 75, n: 100 },\n\t},\n\tnull,\n);\n// Returns: 97.5\n\n// Get names of adult users using pipe (left-to-right)\nconst adultNames = defaultExpressionEngine.apply(\n\t{\n\t\t$pipe: [\n\t\t\t{ $get: \"users\" },\n\t\t\t{ $filter: { $gte: 18 } },\n\t\t\t{ $map: { $get: \"name\" } },\n\t\t],\n\t},\n\tdata,\n);\n// Returns: [\"Fatoumata\"]\n\n// Same operation using compose (right-to-left)\nconst adultNamesComposed = defaultExpressionEngine.apply(\n\t{\n\t\t$compose: [\n\t\t\t{ $map: { $get: \"name\" } },\n\t\t\t{ $filter: { $gte: 18 } },\n\t\t\t{ $get: \"users\" },\n\t\t],\n\t},\n\tdata,\n);\n// Returns: [\"Fatoumata\"]\n\n// Determine child's activity status\nconst activityStatus = defaultExpressionEngine.apply(\n\t{\n\t\t$case: {\n\t\t\tvalue: { $get: \"activity\" },\n\t\t\tcases: [\n\t\t\t\t{ when: \"playing\", then: \"Child is playing\" },\n\t\t\t\t{ when: \"napping\", then: \"Child is napping\" },\n\t\t\t\t{ when: \"eating\", then: \"Child is eating\" },\n\t\t\t],\n\t\t\tdefault: \"Unknown activity\",\n\t\t},\n\t},\n\t{ activity: \"playing\" },\n);\n// Returns: \"Child is playing\"\n\n// Categorize children by age group\nconst ageGroup = defaultExpressionEngine.apply(\n\t{\n\t\t$case: {\n\t\t\tvalue: { $get: \"age\" },\n\t\t\tcases: [\n\t\t\t\t{ when: { $lt: 2 }, then: \"Toddler\" },\n\t\t\t\t{ when: { $lt: 5 }, then: \"Preschooler\" },\n\t\t\t\t{ when: { $gte: 5 }, then: \"School age\" },\n\t\t\t],\n\t\t\tdefault: \"Unknown age group\",\n\t\t},\n\t},\n\t{ age: 4 },\n);\n// Returns: \"Preschooler\"\n\n// Generate random data with parameters\nconst randomValue = defaultExpressionEngine.apply({ $random: {} }, null);\n// Returns: 0.7234 (random number 0-1)\n\nconst randomInt = defaultExpressionEngine.apply(\n\t{\n\t\t$random: { min: 1, max: 100, precision: 0 },\n\t},\n\tnull,\n);\n// Returns: 42 (random integer 1-99)\n\nconst randomPrice = defaultExpressionEngine.apply(\n\t{\n\t\t$random: { min: 10, max: 50, precision: 2 },\n\t},\n\tnull,\n);\n// Returns: 23.45 (random price with 2 decimal places)\n\nconst uniqueId = defaultExpressionEngine.apply({ $uuid: null }, null);\n// Returns: \"f47ac10b-58cc-4372-a567-0e02b2c3d479\" (unique UUID)\n\n// Get current time information\nconst utcTime = defaultExpressionEngine.apply({ $nowUTC: null }, null);\n// Returns: \"2024-01-01T12:00:00.000Z\" (UTC time string)\n\nconst localTime = defaultExpressionEngine.apply({ $nowLocal: null }, null);\n// Returns: \"2024-01-01T05:00:00.000-07:00\" (local time with timezone)\n\nconst timestamp = defaultExpressionEngine.apply({ $timestamp: null }, null);\n// Returns: 1704067200000 (current timestamp)\n\n// Use in conditional logic\nconst sessionId = defaultExpressionEngine.apply(\n\t{\n\t\t$if: {\n\t\t\tif: { $eq: null },\n\t\t\tthen: { $uuid: null },\n\t\t\telse: { $get: \"existingId\" },\n\t\t},\n\t},\n\t{ existingId: null },\n);\n// Returns: new UUID since existingId is null\n\n// Evaluate static expressions\nconst staticExpr = { $sum: [10, 20, 30] };\nconst precomputed = defaultExpressionEngine.evaluate(staticExpr);\nconsole.log(\"Static result:\", precomputed); // 60\n\n// Evaluate static query expressions\nconst queryExpression = {\n\t$if: {\n\t\tif: true, // Static condition\n\t\tthen: { $sum: [1, 2, 3] }, // Static calculation\n\t\telse: { $get: \"fallbackValue\" },\n\t},\n};\n\nconst optimized = defaultExpressionEngine.evaluate(queryExpression);\nconsole.log(\"Pre-computed result:\", optimized); // 6\n```\n\n### Query Enhancement\n\n```json\n// In a Data Prism query\nconst query = {\n  \"type\": \"products\",\n  \"where\": {\n    \"$and\": [\n      { \"$gte\": 10 },\n      { \"$lte\": 100 },\n      { \"$eq\": true }\n    ]\n  },\n  \"select\": {\n    \"name\": \"name\",\n    \"price\": \"price\",\n    \"priceWithTax\": { \"$sum\": [\"price\", \"tax\"] },\n    \"category\": \"category\"\n  }\n};\n```\n\n### Custom Operations\n\n```javascript\nimport {\n\tcreateExpressionEngine,\n\tdefaultExpressions,\n} from \"@data-prism/expressions\";\n\nconst customEngine = createExpressionEngine({\n\t...defaultExpressions,\n\n\t// Custom string operation\n\t$titleCase: {\n\t\tapply: (str) => {\n\t\t\treturn str\n\t\t\t\t.toLowerCase()\n\t\t\t\t.split(\" \")\n\t\t\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t\t\t.join(\" \");\n\t\t},\n\t},\n\n\t// Custom validation operation\n\t$isValidEmail: {\n\t\tapply: (email) => {\n\t\t\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\t\t\treturn emailRegex.test(email);\n\t\t},\n\t},\n});\n\n// Use custom operations\nconst result = customEngine.apply({ $titleCase: \"paul bunyan\" }, null);\n// Returns: \"Paul Bunyan\"\n```\n\n### Expressions for Reusable Logic\n\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/expressions\";\n\n// Define reusable expression\nconst discountPriceExpression = {\n\t$if: {\n\t\tif: { $gt: 0 },\n\t\tthen: { $sum: [\"price\", \"discount\"] },\n\t\telse: { $get: \"price\" },\n\t},\n};\n\n// Apply to multiple products\nconst products = [\n\t{ name: \"Laptop\", price: 1000, discount: -100 },\n\t{ name: \"Mouse\", price: 50, discount: -2.5 },\n\t{ name: \"Keyboard\", price: 100, discount: 0 },\n];\n\nconst discountedPrices = products.map((product) =>\n\tdefaultExpressionEngine.apply(discountPriceExpression, product),\n);\n// Returns: [900, 47.5, 100]\n```\n\n## Integration with Data Prism Core\n\nExpressions work seamlessly with Data Prism queries:\n\n```javascript\nimport { defaultExpressionEngine } from \"@data-prism/expressions\";\nimport { queryGraph } from \"@data-prism/core\";\n\nconst query = {\n\ttype: \"users\",\n\twhere: {\n\t\t$and: [{ $gte: 21 }, { $eq: \"active\" }],\n\t},\n\tselect: {\n\t\tname: \"name\",\n\t\tisAdult: { $gte: 18 },\n\t\tageGroup: {\n\t\t\t$case: {\n\t\t\t\tvalue: { $get: \"age\" },\n\t\t\t\tcases: [\n\t\t\t\t\t{ when: { $lt: 30 }, then: \"young\" },\n\t\t\t\t\t{ when: { $lt: 50 }, then: \"middle\" },\n\t\t\t\t],\n\t\t\t\tdefault: \"senior\",\n\t\t\t},\n\t\t},\n\t},\n};\n\n// Use with expression engine in query options\nconst results = queryGraph(schema, query, graph, {\n\texpressionEngine: defaultExpressionEngine,\n});\n```\n\n## Related Packages\n\n- `@data-prism/core` - Core schema and querying functionality\n- `@data-prism/memory-store` - In-memory data store with expression support\n- `@data-prism/postgres-store` - PostgreSQL backend with SQL expression compilation\n","readmeFilename":"README.md"}