diff --git a/remix/app/Providers/Chakra/ChakraWrapper.tsx b/remix/app/Providers/Chakra/ChakraWrapper.tsx new file mode 100644 index 0000000..4f9c2d4 --- /dev/null +++ b/remix/app/Providers/Chakra/ChakraWrapper.tsx @@ -0,0 +1,5 @@ +import { ChakraProvider } from '@chakra-ui/react' +import { theme } from './theme' +export const ChakraWrapper = props => { + return {props.children} +} diff --git a/remix/app/Providers/Chakra/colors.tsx b/remix/app/Providers/Chakra/colors.tsx new file mode 100644 index 0000000..58ede34 --- /dev/null +++ b/remix/app/Providers/Chakra/colors.tsx @@ -0,0 +1,44 @@ +const g = { + grey: '#F1F1F3', + greys: { + light: '#F1F1F3', + medium: '#E0E0E0', + dark: '#BDBDBD' + } +} + +g.gray = g.grey +g.grays = g.greys + +export const colors = { + white: '#FFFFFF', + ...g, + black: '#000000', + // all colors of the chakras + chakras: { + root: '#C62828', + sacral: '#FF7043', + solarPlexus: '#FFEE58', + heart: '#66BB6A', + throat: '#42A5F5', + thirdEye: '#5C6BC0', + crown: '#AB47BC', + red: '#C62828', + orange: '#FF7043', + yellow: '#FFEE58', + green: '#66BB6A', + blue: '#42A5F5', + indigo: '#5C6BC0', + violet: '#AB47BC' + }, + // all colors of the rainbow + rainbow: { + red: '#FF0000', + orange: '#FF7F00', + yellow: '#FFFF00', + green: '#00FF00', + blue: '#0000FF', + indigo: '#4B0082', + violet: '#8F00FF' + } +} diff --git a/remix/app/Providers/Chakra/theme.tsx b/remix/app/Providers/Chakra/theme.tsx new file mode 100644 index 0000000..aeb6ee5 --- /dev/null +++ b/remix/app/Providers/Chakra/theme.tsx @@ -0,0 +1,14 @@ +import { extendTheme } from '@chakra-ui/react' +import { colors } from './colors' + +export const theme = extendTheme({ + colors, + // edit Input defaultProps + components: { + Input: { + defaultProps: { + focusBorderColor: 'transparent' + } + } + } +}) diff --git a/remix/app/Providers/State.tsx b/remix/app/Providers/State.tsx deleted file mode 100644 index ae86e96..0000000 --- a/remix/app/Providers/State.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React, { createContext, useState, useEffect, useCallback } from "react" - -export const StateContext = createContext(null) - -export const StateProvider = (props: any): JSX.Element => { - - const [state, setState] = useState({}) - - const addState = useCallback( - (newState: any) => { - setState(prevState => { - return { - ...prevState, - ...newState - } - }) - }, - [] - ) - - useEffect(() => { - try { - window.addState = addState - } catch { - // nothing - } - }, []) - - return {props?.children} -} - -export const withState = (Component: any) => (props: any) => ( - - {props => } - -) - -export interface StateContextInterface { - state: any - addState: any -} diff --git a/remix/app/Providers/ThingtimeProvider.tsx b/remix/app/Providers/ThingtimeProvider.tsx new file mode 100644 index 0000000..8c02be4 --- /dev/null +++ b/remix/app/Providers/ThingtimeProvider.tsx @@ -0,0 +1,94 @@ +import React, { createContext } from 'react' +import { sanitise } from '~/functions/path' +import { smarts } from '~/smarts' + +export interface ThingtimeContextInterface { + thingtime: any + setThingtime: any +} + +export const ThingtimeContext = createContext( + null +) + +try { + window.smarts = smarts +} catch (err) { + // nothing +} + +const initialThingtime = { + nav: {}, + settings: { + showCommander: true, + clearCommanderOnToggle: true, + clearCommanderContextOnToggle: true + } +} + +export const ThingtimeProvider = (props: any): JSX.Element => { + const [thingtime, set] = React.useState(initialThingtime) + + const setThingtime = React.useCallback( + (path, value) => { + const prevThingtime = thingtime + + const newThingtime = { + ...prevThingtime + } + + // check if first characters of path starts with thingtime or tt and strip from path + + path = sanitise(path) + + // log the path and value + console.log('nik ThingtimeProvider setThingtime path', path) + console.log('nik ThingtimeProvider setThingtime value', value) + + smarts.setsmart(newThingtime, path, value) + + set(newThingtime) + }, + [thingtime] + ) + + const getThingtime = React.useCallback( + (...args) => { + const path = args[0] + if (path === 'thingtime' || path === 'tt' || !path) { + return thingtime + } + return smarts.getsmart(thingtime, path) + }, + [thingtime] + ) + + React.useEffect(() => { + try { + window.setThingtime = setThingtime + window.thingtime = thingtime + } catch { + // nothing + } + + const keyListener = e => {} + + window.addEventListener('keydown', keyListener) + + return () => { + window.removeEventListener('keydown', keyListener) + } + }, [setThingtime, thingtime]) + + const value = { + thingtime, + setThingtime, + getThingtime + } + + return ( + + {props?.children} + + ) +} diff --git a/remix/app/components/Commander/Commander.tsx b/remix/app/components/Commander/Commander.tsx new file mode 100644 index 0000000..8872090 --- /dev/null +++ b/remix/app/components/Commander/Commander.tsx @@ -0,0 +1,223 @@ +import React from 'react' +import { Center, Box, Flex, Input } from '@chakra-ui/react' +import { useThingtime } from '../Thingtime/useThingtime' +import { Thingtime } from '../Thingtime/Thingtime' +import { sanitise } from '~/functions/path' + +export const Commander = props => { + const { thingtime, setThingtime, getThingtime } = useThingtime() + + const [contextPath, setContextPath] = React.useState() + + const [showContext, setShowContext] = React.useState(false) + + const contextValue = React.useMemo(() => { + console.log('thingtime updated!') + const ret = getThingtime(contextPath) + console.log('nik ret', ret) + return ret + }, [contextPath, getThingtime]) + + const showCommander = React.useMemo(() => { + console.log( + 'nik thingtime?.settings?.showCommander', + thingtime?.settings?.showCommander + ) + return thingtime?.settings?.showCommander + }, [thingtime?.settings?.showCommander]) + + React.useEffect(() => { + if (thingtime?.settings?.clearCommanderOnToggle) { + setValue('') + } + if (showCommander) { + inputRef?.current?.focus?.() + } + }, [showCommander, thingtime]) + + const inputRef = React.useRef() + + const [value, setValue] = React.useState('') + + const onChange = React.useCallback(e => { + setValue(e.target.value) + }, []) + + const onEnter = React.useCallback( + props => { + // if first characters of value equal tt. then run command + // or if first character is a dot then run command + try { + const isTT = value?.slice(0, 3) === 'tt.' + const isDot = value?.slice(0, 1) === '.' + const executeCommand = isTT || isDot + if (executeCommand) { + const command = isTT ? value?.slice(3) : value?.slice(1) + const sanitisedCommand = sanitise(command) + console.log('nik command', command) + + console.log('setting to thingtime', thingtime) + + const commandIsSetter = command?.includes('=') + + if (commandIsSetter) { + // nothing + const [pathRaw, valRaw] = sanitisedCommand?.split('=') + const path = pathRaw.trim() + const val = valRaw.trim() + console.log('nik path', path) + console.log('nik val', val) + try { + const realVal = eval(val) + console.log('nik realVal', realVal) + setThingtime(path, realVal) + } catch (err) { + console.log('setThingtime errored in Commander', err) + } + // setContextPath(path) + } else { + const val = getThingtime(sanitisedCommand) + + console.log('setting to val', val) + + setContextPath(sanitisedCommand) + setShowContext(true) + } + } + } catch (err) { + console.error('Caught error on commander onEnter', err) + } + }, + [value, thingtime, getThingtime, setThingtime] + ) + + // trigger on enter + const onKeyDown = React.useCallback( + e => { + if (e.key === 'Enter') { + console.log('nik enter') + e.preventDefault() + e.stopPropagation() + onEnter({ e }) + // setThingtime( + // 'settings.showCommander', + // !thingtime?.settings?.showCommander + // ) + } + }, + [thingtime?.settings?.showCommander, onEnter] + ) + + const openCommander = React.useCallback(() => { + setThingtime('settings.showCommander', true) + }, [setThingtime]) + + const closeCommander = React.useCallback(() => { + setThingtime('settings.showCommander', false) + setShowContext(false) + setContextPath(undefined) + }, [setThingtime]) + + const toggleCommander = React.useCallback(() => { + if (thingtime?.settings?.showCommander) { + closeCommander() + } else { + openCommander() + } + }, [thingtime?.settings?.showCommander, closeCommander, openCommander]) + + React.useEffect(() => { + const keyListener = (e: any) => { + if (e?.metaKey && e?.code === 'KeyP') { + console.log('nik heard event') + e.preventDefault() + e.stopPropagation() + toggleCommander() + } + // if key escape close all modals + if (e?.code === 'Escape') { + closeCommander() + } + } + + window.addEventListener('keydown', keyListener) + + return () => { + window.removeEventListener('keydown', keyListener) + } + }, [setThingtime, thingtime]) + + return ( +
+
+ + + +
+
+ + +
+
+ ) +} diff --git a/remix/app/components/Nav/Nav.tsx b/remix/app/components/Nav/Nav.tsx index 6256aa1..18eaabc 100644 --- a/remix/app/components/Nav/Nav.tsx +++ b/remix/app/components/Nav/Nav.tsx @@ -1,7 +1,8 @@ import React from 'react' -import { Flex } from '@chakra-ui/react' +import { Box, Flex } from '@chakra-ui/react' import { RainbowSkeleton } from '../Skeleton/RainbowSkeleton' import { ProfileDrawer } from './ProfileDrawer' +import { Commander } from '../Commander/Commander' export const Nav = props => { const [profileDrawerOpen, setProfileDrawerOpen] = React.useState(false) @@ -12,33 +13,33 @@ export const Nav = props => { return ( <> - - - {/* - */} - + + + + + {/* + */} + + {/* */} ) diff --git a/remix/app/components/Skeleton/RainbowSkeleton.tsx b/remix/app/components/Skeleton/RainbowSkeleton.tsx index f2ab80f..018a63a 100644 --- a/remix/app/components/Skeleton/RainbowSkeleton.tsx +++ b/remix/app/components/Skeleton/RainbowSkeleton.tsx @@ -31,7 +31,6 @@ export const RainbowSkeleton = props => { w='10px' h='8px' borderRadius={'2px'} - bg={'rgba(0,0,0,0.1)'} sx={{ '@keyframes placeholder-rainbow': keyframes, '@keyframes placeholder-opacity': { @@ -39,7 +38,7 @@ export const RainbowSkeleton = props => { '100%': { opacity: 1 } }, // add delay - animation: `placeholder-rainbow 3s infinite linear, placeholder-opacity 1.3s linear 0s infinite alternate none running}` + animation: `placeholder-rainbow 8s infinite linear, placeholder-opacity 1.3s linear 0s infinite alternate none running}` }} {...props} > diff --git a/remix/app/components/Thingtime/Thingtime.tsx b/remix/app/components/Thingtime/Thingtime.tsx index 2a6bdef..3e53dc4 100644 --- a/remix/app/components/Thingtime/Thingtime.tsx +++ b/remix/app/components/Thingtime/Thingtime.tsx @@ -1,23 +1,29 @@ import React from 'react' import { Box, Flex } from '@chakra-ui/react' import { Safe } from '../Safety/Safe' -import { useState } from './useState' +import { useThingtime } from './useThingtime' export const Thingtime = props => { // const uuid = React.useMemo(() => { // return Math.random().toString(36).substring(7) // }, []) - const uuid = React.useRef(Math.random().toString(36).substring(7)) - const { state } = useState() + const [uuid, setUuid] = React.useState() + + // will only run on the client + React.useEffect(() => { + setUuid(Math.random().toString(36).substring(7)) + }, []) + + const { thingtime } = useThingtime() React.useEffect(() => { - console.log('nik state?.test changed', state?.test) - }, [state?.test]) + // console.log('nik thingtime?.test changed', thingtime?.test) + }, [thingtime?.test]) React.useEffect(() => { - console.log('nik state changed', state) - }, [state]) + // console.log('nik thingtime changed', thingtime) + }, [thingtime]) const depth = React.useMemo(() => { return props?.depth || 1 @@ -37,7 +43,9 @@ export const Thingtime = props => { const keys = React.useMemo(() => { if (validKeyTypes?.includes(typeof thing)) { - return Object.keys(thing) + const keysRet = Object.keys(thing) + console.log('nik keysRet', keysRet) + return keysRet } else { return [] } @@ -55,7 +63,20 @@ export const Thingtime = props => { } else if (type === 'boolean') { return thing ? 'true' : 'false' } else if (type === 'object') { - return JSON.stringify(thing, null, 2) + if (!keys?.length) { + return 'Empty object' + } + + try { + return JSON.stringify(thing, null, 2) + } catch (err) { + console.error( + 'Caught error making renderableValue of thing', + err, + thing + ) + return 'Circular reference in object.' + } } else { return null } @@ -118,8 +139,9 @@ export const Thingtime = props => { // w={'500px'} // w={['200px', '500px']} maxW='100%' + py={props?.path ? 3 : 0} pl={[4, 6]} - pr={[4, 6]} + // pr={[4, 6]} > {keysToUse?.length && keysToUse.map((key, idx) => { diff --git a/remix/app/components/Thingtime/useState.tsx b/remix/app/components/Thingtime/useState.tsx deleted file mode 100644 index b76406b..0000000 --- a/remix/app/components/Thingtime/useState.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React, { useContext } from 'react' - -import { StateContext } from '~/Providers/State' - -const getGlobal = () => { - try { - return window - } catch { - return globalThis - } -} - -export const useState = (props?: any) => { - - const { state, addState } = useContext(StateContext) - - return { state, addState } -} diff --git a/remix/app/components/Thingtime/useThingtime.tsx b/remix/app/components/Thingtime/useThingtime.tsx new file mode 100644 index 0000000..1602e1d --- /dev/null +++ b/remix/app/components/Thingtime/useThingtime.tsx @@ -0,0 +1,19 @@ +import React, { useContext } from 'react' + +import { ThingtimeContext } from '~/Providers/ThingtimeProvider' + +const getGlobal = () => { + try { + return window + } catch { + return globalThis + } +} + +export const useThingtime = (props?: any) => { + const value = useContext(ThingtimeContext) + + const { thingtime, setThingtime, getThingtime } = value + + return value +} diff --git a/remix/app/components/rainbowText.tsx b/remix/app/components/rainbowText.tsx index 5cc12f1..811baa8 100644 --- a/remix/app/components/rainbowText.tsx +++ b/remix/app/components/rainbowText.tsx @@ -5,13 +5,13 @@ export const RainbowText = props => { return ( , document) diff --git a/remix/app/functions/path.tsx b/remix/app/functions/path.tsx new file mode 100644 index 0000000..ef5665c --- /dev/null +++ b/remix/app/functions/path.tsx @@ -0,0 +1,13 @@ +export const sanitise = str => { + const isTT = str?.slice(0, 3) === 'tt.' + const isThingtime = str?.slice(0, 9) === 'thingtime.' + + if (isTT) { + str = str?.slice(3) + } + if (isThingtime) { + str = str?.slice(9) + } + + return str +} diff --git a/remix/app/root.tsx b/remix/app/root.tsx index 04c6c59..6a85bee 100644 --- a/remix/app/root.tsx +++ b/remix/app/root.tsx @@ -1,4 +1,4 @@ -import { ChakraProvider } from '@chakra-ui/react' +import { ChakraWrapper } from './Providers/Chakra/ChakraWrapper' // import type { MetaFunction } from "@vercel/remix" import { Links, @@ -10,7 +10,7 @@ import { } from '@remix-run/react' import { Analytics } from '@vercel/analytics/react' import { Main } from './components/Layout/Main' -import { StateProvider } from './Providers/State' +import { ThingtimeProvider } from './Providers/ThingtimeProvider' function Document ({ children, @@ -29,7 +29,7 @@ function Document ({ -
{children}
+ {children} @@ -42,17 +42,18 @@ function Document ({ export default function App () { return ( - - - - - + + +
+ +
+
+
) } // limiter - const setThingtime = glob => { try { glob.thingtime = { diff --git a/remix/app/smarts/index.tsx b/remix/app/smarts/index.tsx new file mode 100644 index 0000000..78382f0 --- /dev/null +++ b/remix/app/smarts/index.tsx @@ -0,0 +1,2857 @@ +import { v4 as uuidv4 } from 'uuid' +// import { Buffer } from 'buffer' +// weird hack for remix client-side logic +try { + window.process = { + env: {} + } + window.Buffer = () => {} + // window.Buffer = Buffer +} catch (err) { + // nothing +} + +const babel = require('@babel/standalone') + +babel.template = require('@babel/template').default +babel.t = require('@babel/types') +babel.generator = require('@babel/generator').default +babel.babylon = require('@babel/parser') +babel.prettier = require('prettier') + +const objList = [] +const stringList = [] + +// ES6? +// import { uuidv4 as uuid } from 'uuid' + +// import babel from '@babel/standalone' + +// import template from '@babel/template' +// babel.template = template +// import t from '@babel/types' +// babel.t = t +// import generator from '@babel/generator' +// babel.generator = generator +// import babylon from '@babel/parser' +// babel.babylon = babylon +// import prettier from 'prettier' +// babel.prettier = prettier + +export const local = {} +export const t = babel?.t + +export const getBabel = () => { + return babel +} +export const uuid = uuidv4 +export const pause = (value, opts) => { + return stringify(value, opts) +} +export const save = (value, opts) => { + return stringify(value, opts) +} +export const toJavascript = (value, opts = {}) => { + let defaultOpts = { + wrapInFunction: true, + declarations: [], + identifier: 'obj', + keys: { + obj: 1 + }, + dependancies: {}, + mappings: [], + seen: [], + db: [] + } + Object.assign(defaultOpts, opts) + opts = defaultOpts + toJavascriptAux(value, opts) + // sort declarations by dependancies + for (let declaration of opts.declarations) { + if (declaration.type === 'ExpressionStatement') { + // nothing + } else { + let key = declaration.declarations[0].id.name + let dependancies = opts.dependancies[key] + let dependancyCheck = {} + for (let dependancy of dependancies) { + dependancyCheck[dependancy] = false + } + let sortableDeclarationIndex = 0 + let insertionIndex = 0 + for (let sortableDeclaration of opts.declarations) { + if (sortableDeclaration.type === 'ExpressionStatement') { + // nothing + } else { + let sortableDeclarationKey = + sortableDeclaration.declarations[0].id.name + if (dependancyCheck[sortableDeclarationKey] === false) { + insertionIndex = sortableDeclarationIndex + 1 + dependancyCheck[sortableDeclarationKey] = true + } + } + // increment iterator index + sortableDeclarationIndex++ + } + let declarationIndex = opts.declarations.indexOf(declaration) + opts.declarations.splice(declarationIndex, 1) + opts.declarations.splice(insertionIndex, 0, declaration) + } + } + let program + if (opts.wrapInFunction && !opts.moduleExport) { + opts.declarations.push(t.returnStatement(t.identifier('obj'))) + let expression = t.expressionStatement( + t.callExpression( + t.functionExpression(null, [], t.blockStatement(opts.declarations)), + [] + ) + ) + program = t.program([expression]) + } else { + if (opts.moduleExport) { + opts.declarations.push( + t.expressionStatement( + t.assignmentExpression( + '=', + t.memberExpression(t.identifier('module'), t.identifier('exports')), + t.identifier('obj') + ) + ) + ) + } + program = t.program(opts.declarations) + } + let stringifiedProgram = getBabel().generator(program).code + return getBabel().prettier.format(stringifiedProgram, { + semi: false, + parser: 'babel', + useTabs: true + }) +} +export const toJavascriptAux = (value, opts) => { + if (typeof value === 'object') { + if (!opts.seen.includes(value)) { + // update map and seen + opts.seen.push(value) + let properties = createObjectProperties(value, opts) + let declaration = t.variableDeclaration('let', [ + t.variableDeclarator( + t.identifier(opts.identifier), + t.objectExpression(properties) + ) + ]) + opts.declarations.unshift(declaration) + for (let key of Object.keys(value)) { + let property = properties.find(v => { + return v.value.name === key + }) + if (property) { + let identifier = property.value.name + toJavascriptAux(value[key], { ...opts, identifier }) + } + } + } + } else if (typeof value === 'string') { + let declaration = t.variableDeclaration('let', [ + t.variableDeclarator( + t.identifier(opts.identifier), + t.stringLiteral(value) + ) + ]) + opts.declarations.unshift(declaration) + } +} +export const createObjectProperties = (value, opts) => { + let properties = [] + let dependancies = opts.dependancies[opts.identifier] + if (!dependancies) dependancies = opts.dependancies[opts.identifier] = [] + for (let key of Object.keys(value)) { + if (value[key] === value) { + opts.declarations.push( + t.expressionStatement( + t.assignmentExpression( + '=', + t.memberExpression( + t.identifier(opts.identifier), + t.identifier(key) + ), + t.identifier(opts.identifier) + ) + ) + ) + } else { + if (!opts.db.includes(value[key])) { + opts.db.push(value[key]) + if (opts.keys[key] === undefined) { + opts.keys[key] = 1 + } + let keyIncrement = opts.keys[key] + if (keyIncrement == 1) { + opts.mappings.push(key) + } else { + opts.mappings.push(key + keyIncrement) + } + opts.keys[key]++ + } + let identifier = opts.mappings[opts.db.indexOf(value[key])] + dependancies.push(identifier) + properties.push( + t.objectProperty( + t.identifier(key), + t.identifier(identifier), + false, + key == identifier + ) + ) + } + } + return properties +} +export const serialize = (value, opts = {}) => { + opts.strictFunctions = false + opts.serializeArrayProps = true + return stringify(value, opts) +} +export const stringify = (value, opts = {}) => { + let schema = { + stringifier: stringifier, + replace (key, value) { + if (opts.firstRun) { + opts.firstRun = !opts.firstRun + return value + } + var after = opts.stringifier(key, value, opts) + + const type = typeof after.value + + if (type === 'object') { + if (after === null || after.value === null) { + const ret = after.value + return ret + } + } else if (type === 'string') { + const ret = + opts.known.get(after.key) || setKnown(opts.known, opts.input, after) + return ret + } + + return after.value + }, + strictFunctions: true, + firstRun: undefined, + known: new Map(), + input: [], + output: [] + } + + Object.keys(schema).forEach(key => { + if (getsmart(opts, epp(key), { undefined: true }, true).undefined == true) { + opts[key] = schema[key] + } + }) + + opts.virtual = opts.stringifier('', value, opts) + for ( + let i = parseInt(setKnown(opts.known, opts.input, opts.virtual)); + i < opts.input.length; + i++ + ) { + opts.firstRun = true + try { + opts.output[i] = JSON.stringify(opts.input[i], opts.replace, opts.space) + } catch (err) { + console.error(err) + } + } + return '[' + opts.output.join(',') + ']' +} +export const replacer = (key, value) => { + const opts = opts || {} + + if (opts.firstRun) { + opts.firstRun = !opts.firstRun + return value + } + var after = opts.stringifier(key, value, opts) + // replace with if statements + + const type = typeof after.value + + if (type === 'object') { + if (after === null) { + const ret = after.value + return ret + } + } else if (type === 'string') { + const ret = + opts.known.get(after.key) || setKnown(opts.known, opts.input, after) + return ret + } + return after.value +} +export const setKnown = (known, input, virtual) => { + var index = String(input.push(virtual.value) - 1) + known.set(virtual.key, index) + return index +} +export const stringifier = (key, val, opts) => { + let ret = { value: val, key: val } + if ( + val instanceof Function && + typeof val.toString === 'function' && + (!opts.strictFunctions || typeof val.$scopes != 'undefined') + ) { + let known = opts.known.get(ret.key) + ret = { + value: known || { + type: 'function', + js: val.toString(), + $scopes: val.$scopes, + $context: val.$context, + ...val + }, + key: val + } + if (ret.value.js == 'function () { [native code] }') return + if (typeof known == 'undefined') setKnown(opts.known, opts.input, ret) + } else if (ret.value === Infinity && typeof ret.value != 'string') { + let known = opts.known.get(ret.key) + ret = { + value: known || { + type: 'number', + js: 'Infinity', + $scopes: [], + $context: {} + }, + key: val + } + if (typeof known == 'undefined') setKnown(opts.known, opts.input, ret) + } else if (typeof ret.value === 'undefined') { + ret = { + value: { + type: 'undefined', + js: 'undefined' + }, + key: val + } + } else if (ret.value instanceof Array && opts.serializeArrayProps) { + let known = opts.known.get(ret.key) + ret = { + value: known + ? ret.value + : { + type: 'Array', + js: ret.value, + uuid: ret.value.uuid + }, + key: val + } + setKnown(opts.known, opts.input, ret) + } + return ret +} +export const primitives = value => { + return value instanceof String ? String(value) : value +} +export const Primitives = (key, value) => { + return typeof value === 'string' ? new String(value) : value +} +export const play = (text, opts) => { + return parse(text, opts) +} +export const load = (text, opts = {}) => { + opts.strictFunctions = false + return parse(text, opts) +} +export const parse = (text, opts = {}) => { + let schema = { + // parser: eval('(function '+parser+')'), + parser: parser(opts), + value: {}, + strictFunctions: true, + noFunctions: false, + firstPass: true, + output: new Map() + } + + Object.keys(schema).forEach(key => { + if (getsmart(opts, epp(key), { undefined: true }, true).undefined == true) { + opts[key] = schema[key] + } + }) + + // opts.parser = opts.parser.bind(opts) + opts.input = JSON.parse(text, Primitives) + opts.firstPass = false + opts.input = opts.input.map(primitives) + opts.value = opts.input[0] + let isObject = typeof opts.value === 'object' && opts.value + var tmp = isObject + ? revive(opts.input, opts.output, opts.value, opts.parser, opts) + : opts.value + + opts.replaceMode = true + let ret = revive(opts.input, new Map(), tmp, opts.parser, opts) + ret = opts.parser('', tmp, opts) + return ret +} +export const parser = opts => { + return function (key, val) { + if (val.js && val.type === 'Array') { + const ret = opts.input[opts.output.get(val)].js + ret.uuid = opts.input[opts.output.get(val)].uuid + return ret + } else if ( + val.js && + val.type === 'function' && + opts.replaceMode && + !opts.noFunctions + ) { + let ret = opts.input[opts.output.get(val)] + if (typeof ret == val.type) return ret + let uuid = jsUUID() + var fn + var scopedEval + if (val.$scopedEval && typeof val.$scopedEval == 'function') { + scopedEval = val.$scopedEval + } else { + var fns = createScopedEval(uuid) + + try { + fn = eval(`(${fns})`) + var input = { val, smarts } + scopedEval = fn(input) + } catch (err) { + console.log('Caught error evaling createScopedEval', err) + } + } + + ret = scopedEval({ val }) + try { + Object.defineProperty(ret, '$scopes', { + value: val.$scopes, + enumerable: true + }) + if (val.uuid) { + ret.uuid = val.uuid + } + } catch (err) { + if (opts.verbose) console.error(err) + } + try { + Object.defineProperty(ret, '$context', { + value: val.$context, + enumerable: true + }) + } catch (err) { + if (opts.verbose) console.error(err) + } + try { + Object.defineProperty(ret, '$scopedEval', { + value: scopedEval, + enumerable: true + }) + } catch (err) { + if (opts.verbose) console.error(err) + } + opts.input[opts.output.get(val)] = ret + return ret + } else if (opts.replaceMode) { + return val + } + return Primitives(key, val) + } +} +export const revive = (input, parsed, output, parser, opts) => { + return Object.keys(output).reduce((output, key) => { + var value = output[key] + // if the value hasn't been revived yet + if (value instanceof String) { + var tmp = input[value] + if (typeof tmp === 'object' && !parsed.get(tmp)) { + parsed.set(tmp, value) + output[key] = primitives( + parser(key, revive(input, parsed, tmp, parser, opts)) + ) + } else { + try { + output[key] = primitives(parser(key, tmp)) + } catch (err) { + delete output[key] + } + } + } else { + try { + if (opts.replaceMode) { + // output[key] = primitives(parser(key, revive(input, parsed, value, parser, opts))) + value = parser(key, value) + if (typeof value === 'object' && !parsed.get(value)) { + parsed.set(value, value) + output[key] = primitives( + parser(key, revive(input, parsed, value, parser, opts)) + ) + } else { + try { + output[key] = primitives(value) + } catch (err) { + delete output[key] + } + } + } else { + output[key] = primitives(parser(key, value)) + } + } catch (err) { + delete output[key] + } + } + return output + }, output) +} +export const createScopedEval = uuid => { + let ret = /*javascript*/ ` + function createScopedEval(${uuid}){ + + // scopeCode + ${uuid}.scopeCode = ${uuid}.scopeCode || ${uuid}.getBabel().template.ast('try{}catch(err){console.log(err)}') + ${uuid}.previousScopeCode = ${uuid}.currentScopeCode || ${uuid}.scopeCode + ${uuid}.currentScopeCode = ${uuid}.scopeCode.block.body.length ? ${uuid}.getBabel().template.ast('try{}catch(err){console.log(err)}') : ${uuid}.scopeCode + if(${uuid}.previousScopeCode != ${uuid}.currentScopeCode){ + ${uuid}.previousScopeCode.block.body.push( + ${uuid}.currentScopeCode + ) + } + ${uuid}.closureIndex = ${uuid}.closureIndex || 0 + ${uuid}.closure = ${uuid}.getsmart.bind(this)(${uuid}, ${ + /*javascript*/ `\`val.$scopes.\${${uuid}.closureIndex}\`` + }, {}) + ${uuid}.variableKeys = Object.keys(${uuid}.closure) + ${uuid}.variableMap = ${uuid}.getsmart.bind(this)(${uuid}, ${ + /*javascript*/ `\`val.$context.$variableMaps.\${${uuid}.closureIndex}\`` + }, []) + ${uuid}.allowedIdentifiers = ['let','var','const'] + ${uuid}.variableKeys.forEach((key)=>{ + if( + typeof ${uuid}.variableMap[key] == 'string' + && ${uuid}.allowedIdentifiers.indexOf(${uuid}.variableMap[key]) >= 0 + ){ + try{ + ${uuid}.currentScopeCode.block.body.push( + ${uuid}.getBabel().template.ast( + ${ + /*javascript*/ `\` + \${${uuid}.variableMap[key]} \${key} = ${uuid}.val.$scopes[\${${uuid}.closureIndex}]['\${key}'] + \`` + } + ) + ) + }catch(err){console.log(1,err)} + try{ + ${uuid}.currentScopeCode.block.body.push( + ${uuid}.getBabel().template.ast( + ${ + /*javascript*/ `\` + Object.defineProperty( + ${uuid}.val.$scopes[\${${uuid}.closureIndex}], + \${${uuid}.stringify(key)}, + { + get(){ + return \${key} + }, + set(val){ + \${key} = val + }, + enumerable: true + } + ) + \`` + } + ) + ) + }catch(err){console.log(2,err)} + } + // console.log(${uuid}.scopeCode) + }) + // console.log(${uuid}.scopeCode) + ${uuid}.closureIndex++ + if(${uuid}.closureIndex >= ${uuid}.getsmart.bind(this)(${uuid}, 'val.$scopes.length', -1)){ + // console.log(${uuid}.scopeCode) + try{ + ${uuid}.currentScopeCode.block.body.push( + ${uuid}.getBabel().template.ast( + ${ + /*javascript*/ `\` + return \${${uuid}.scopedEval('${uuid}')} + \`` + } + ) + ) + }catch(err){console.log(3,err)} + try{ + ${uuid}.wrapper = ${uuid}.getBabel().template.ast( + ${ + /*javascript*/ `\` + function anonymous(){} + \`` + } + ) + }catch(err){console.log(4,err)} + // console.log(${uuid}.wrapper) + // console.log(${uuid}.scopeCode) + ${uuid}.wrapper.body.body.push(${uuid}.scopeCode) + ${uuid}.scopeCode = ${uuid}.wrapper + ${uuid}.scopeCode = ${uuid}.getBabel().generator( + ${uuid}.scopeCode + ).code + // console.log(${uuid}.scopeCode) + ${uuid}.scopeCode = eval("("+${uuid}.scopeCode+")") + // console.log(${uuid}.scopeCode.toString()) + try { + ${uuid}.val.$scopedEval = ${uuid}.scopeCode() + }catch(err){console.log(5,err)} + // console.log(${uuid}.val.$scopedEval) + // return ${uuid}.scopeCode.toString() + return ${uuid}.val.$scopedEval + } else { + return eval(${ + /*javascript*/ `\`(\${${uuid}.createScopedEval('${uuid}')})\`` + })(${uuid}) + } + } + ` + return ret +} +export const defineVariable = uuid => { + return /*javascript*/ ` + ${uuid.variableType} ${uuid.variableKey} = ${uuid}.$scope[${uuid}.variableKey] + Object.defineProperty( + ${uuid}.$scope, + ${uuid}.variableKey, + { + get(){ + return ${uuid.variableKey} + }, + set(val){ + ${uuid.variableKey} = val + }, + enumerable: true + } + ) + ` +} +export const scopedEval = uuid => { + let ret = /*javascript*/ `function scopedEval(${uuid}){ + if(typeof ${uuid} == 'string'){ + ${uuid} = { + val: { + js: ${uuid} + } + } + } else if(typeof ${uuid} == 'function' && typeof ${uuid}.toString == 'function'){ + ${uuid} = { + val: { + js: ${uuid}.toString() + } + } + } + try { + ${uuid}.ret = eval('('+${uuid}.val.js+')') + } catch(err1){ + try { + ${uuid}.ret = eval('({'+${uuid}.val.js+'})') + ${uuid}.keys = Object.keys(${uuid}.ret) + ${uuid}.ret = ${uuid}.ret[${uuid}.keys[0]] + } catch(err2){ + try { + ${uuid}.ret = eval('({b:'+ ${uuid}.val.js +'})').b + } catch(err3){ + console.error(err1) + console.error(err2) + console.error(err3) + } + } + } + return ${uuid}.ret + } + ` + return ret +} +export const jsUUID = (prefix = 'uuid') => { + return prefix + uuid().replace(/-/g, '') +} +export const context = opts => { + let uuid = gosmart.bind(this)(opts, 'path.context.scope.uuid', jsUUID()) + return eval(/*javascript*/ ` + ( + function(){ + ${contextObject(uuid)} + return ${uuid} + } + )() + `) +} +export const contextObject = uuid => { + return /*javascript*/ ` + let ${uuid} = { + $$uuid: '${uuid}', + $closure: {}, + $variableMap: {}, + $functionScoper: (func)=>{ + Object.defineProperty( + func, + '$scopes', + { + value: (function(arr){ + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { + arr2[i] = arr[i]; + } + return arr2 + })((typeof ${uuid} != 'undefined') ? ${uuid}.$scopes : []), + enumerable: true + } + ) + Object.defineProperty( + func, + '$context', + { + value: ${uuid} + } + ) + return func + }, + $add: (type, name, value)=>{ + ${uuid}.$closure[name] = value + ${uuid}.$variableMap[name] = type + }, + $scopes: (function(arr){ + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { + arr2[i] = arr[i]; + } + return arr2 + })((typeof $context == 'object') ? $context.$scopes : []), + $variableMaps: (function(arr){ + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { + arr2[i] = arr[i]; + } + return arr2 + })((typeof $context == 'object') ? $context.$variableMaps : []), + $contexts: {}, + $contextsList: [], + $parentContexts: [], + $contextStatus: "var", + $mode: (eval("var ${uuid}1 = null"), (typeof ${ + uuid + '1' + } === "undefined")) ? "strict" : "non-strict", + } + ${uuid}.$functionScoper = ${uuid}.$functionScoper(${uuid}.$functionScoper) + ${uuid}.$scopes.splice(0,0,${uuid}.$closure) + ${uuid}.$variableMaps.splice(0,0,${uuid}.$variableMap) + var globalThis = globalThis || global || window || {} + ${uuid}.$contextStatus = ${uuid}.$mode == 'strict' ? '' : 'var' + try { + eval(${ + /*javascript*/ `\`\${${uuid}.$contextStatus} $context = $context || ${uuid}\`` + }) + } catch(err){ + ${uuid}.$contextStatus = '' + } + eval(${ + /*javascript*/ `\`\${${uuid}.$contextStatus} $context = $context || ${uuid}\`` + }) + if(typeof $context == 'object' && $context != ${uuid} && $context.$contexts instanceof Object){ + $context.$contexts[${uuid}.$$uuid] = $context.$contexts[${uuid}.$$uuid] || [] + ${uuid}.$$instance = $context.$contexts[${uuid}.$$uuid].push(${uuid})-1 + ${uuid}.$parentContexts.push($context) + $context.$contextsList.push(${uuid}) + } + if(!globalThis.$contexts){ + globalThis.$contexts = {} + globalThis.$contexts[${uuid}.$$uuid] = [${uuid}] + globalThis.$contextsList = [${uuid}] + ${uuid}.$$instance = 0 + } else if( + globalThis.${uuid}s instanceof Object + && ${uuid}.$parentContexts.length == 0 + && typeof ${uuid}.$$instance == 'undefined' + ){ + globalThis.${uuid}s[${uuid}.$$uuid] = globalThis.$contexts[${uuid}.$$uuid] || [] + ${uuid}.$$instance = globalThis.$contexts[${uuid}.$$uuid].push(${uuid})-1 + globalThis.$contextsList.push(${uuid}) + } + { + let $context = ${uuid} + } + ` +} +export const createContext = opts => { + schema(opts, { + wrapBody: true + }) + let node = opts.aster(/*javascript*/ ` + ${contextObject(opts.uuid)} + `) + node[0].declarations[0].contextDeclaration = true + // so the $functionScoper function doesn't get wrapped or have $context inserted + let property3 = node[0].declarations[0].init.properties[3] + property3.value.scoperWrapped = true + property3.value.body.scopeInitialized = true + let property3ScopesValue = + property3.value.body.body[0].expression.arguments[2].properties[0].value + property3ScopesValue.callee.scoperWrapped = true + property3ScopesValue.callee.body.scopeInitialized = true + let property3ForStatement = property3ScopesValue.callee.body.body[0] + property3ForStatement.body.scopeInitialized = true + property3ForStatement.init.declarations[0].inScope = true + property3ForStatement.init.declarations[1].inScope = true + // so the $add function doesn't get wrapped or have $context inserted + let property4 = node[0].declarations[0].init.properties[4] + property4.value.scoperWrapped = true + property4.value.body.scopeInitialized = true + // so the $scopes self-invoking function doesn't get wrapped or have $context inserted + let property5 = node[0].declarations[0].init.properties[5] + property5.value.callee.scoperWrapped = true + property5.value.callee.body.scopeInitialized = true + let property5ForStatement = property5.value.callee.body.body[0] + property5ForStatement.body.scopeInitialized = true + property5ForStatement.init.declarations[0].inScope = true + property5ForStatement.init.declarations[1].inScope = true + // so the $variableMaps self-invoking function doesn't get wrapped or have $context inserted + let property6 = node[0].declarations[0].init.properties[6] + property6.value.callee.scoperWrapped = true + property6.value.callee.body.scopeInitialized = true + let property6ForStatement = property6.value.callee.body.body[0] + property6ForStatement.body.scopeInitialized = true + property6ForStatement.init.declarations[0].inScope = true + property6ForStatement.init.declarations[1].inScope = true + const node6 = node[6] + // make sure try statement block doesn't get scoped either + node6.block.scopeInitialized = true + // make sure catch statement block doesn't get scoped either + node6.handler.body.scopeInitialized = true + const node8 = node[8] + // make sure if statement block doesn't get scoped either + node8.consequent.scopeInitialized = true + const node9 = node[9] + // make sure if statement block doesn't get scoped either + node9.consequent.scopeInitialized = true + // make sure else if statement block doesn't get scoped either + node9.alternate.consequent.scopeInitialized = true + const node10 = node[10] + node10.scopeInitialized = true + node10.inheritScope = true + node[node.length - 1].lastContextNode = true + if (opts.wrapBody) { + let bodyWrapper = node[node.length - 1] + bodyWrapper.body.push(...opts.path.node.body) + } + addBindingsToContext({ ...opts, node }) + // let addContextToScopeNode = scopeVar({ + // uuid, + // key: '$context', + // type: 'let', + // aster + // }) + // wrapper.body.splice(1,0,addContextToScopeNode) + return node +} +export const createInlineContext = opts => { + let wrapperString = /*javascript*/ ` + for(let ${opts.uuid} = function(){ + // node goes here + return ${opts.uuid} + }() ; a<1;a++){} + ` + let inlineContextNode = opts.aster(wrapperString).init.declarations[0] + let contextBody = createContext({ ...opts, wrapBody: false }) + inlineContextNode.init.callee.body.body.splice(0, 0, ...contextBody) + inlineContextNode.contextDeclaration = true + return inlineContextNode +} +export const addBindingsToContext = opts => { + for (let key in opts.path.scope.bindings) { + let binding = opts.path.scope.bindings[key] + if (binding.kind == 'var') { + let newNode = scopeVar({ + ...opts, + key, + type: binding.kind + }) + opts.node.splice(opts.node.length - 1, 0, newNode) + } + } +} +export const scopeVarCode = opts => { + let ret = /*javascript*/ ` + Object.defineProperty( + ${opts.uuid}.$closure, + ${stringify(opts.key)}, + { + get(){ + return ${opts.key} + }, + set(val){ + ${opts.key} = val + }, + enumerable: true + } + ) && + (${opts.uuid}.$variableMap["${opts.key}"] = "${opts.type}") + ` + return ret +} +export const scopeVarInlineCode = opts => { + let ret = /*javascript*/ ` + let ${jsUUID()} = ( + ${scopeVarCode(opts)} + ) + ` + return ret +} +export const scopeVar = (opts = {}) => { + let string + let thirdArg + let node + if (opts.inline) { + string = scopeVarInlineCode(opts) + node = opts.aster(string) + thirdArg = node.declarations[0].init.left.arguments[2] + node.declarations[0].inScope = true + } else { + string = scopeVarCode(opts) + node = opts.aster(string) + thirdArg = node.expression.left.arguments[2] + } + + let getter = thirdArg.properties[0] + let setter = thirdArg.properties[1] + getter.body.scopeInitialized = true + setter.body.scopeInitialized = true + getter.body.scoperWrapped = true + setter.body.scoperWrapped = true + getter.scoperWrapped = true + setter.scoperWrapped = true + if (opts.inline) return node.declarations[0] + return node +} +export const functionWrapper = (uuid, path, aster) => { + let wrapper = aster(/*javascript*/ ` + ${uuid}.$functionScoper() + `) + wrapper.expression.arguments.push(path.node) + return wrapper +} +export const bodyInsert = (index, body, aster, ...things) => { + body.splice(index, 0, ...things) + return things.length +} +export const initBlock = (path, aster) => { + if (!path.node.scopeInitialized) { + path.node.scopeInitialized = true + let uuid = getPathUUID({ path }) + let contextNode = createContext({ uuid, aster, path }) + path.node.body = contextNode + } +} +export const getNodeUUID = opts => { + if ( + opts.node && + opts.node.type != 'BlockStatement' && + opts.node.type != 'Program' + ) + return getNodeUUID({ + ...opts, + node: opts.node.body || opts.node.block + }) + return gosmart.bind(this)(opts.node, 'uuid', jsUUID()) +} +export const getPathUUID = opts => { + if ( + opts.path.context.scope.path.node.inheritScope || + opts.path.scope.path.node.inheritScope + ) + return getPathUUID({ ...opts, path: opts.path.parentPath }) + return getNodeUUID({ + ...opts, + node: opts.path.context.scope.path.node + }) +} +export const babelPlugin = babel => { + const aster = babel.template.ast + + let metaVisitor = { + Program (path) { + initBlock(path, aster) + }, + BlockStatement (path) { + initBlock(path, aster) + }, + ForInStatement () { + // nothing + }, + // ForInStatement (path) { + // path = path + // }, + ObjectMethod (path) { + let name = path.node.key.name + let replacement = aster(/*javascript*/ ` + let a = { + ${name}: function ${name}(){} + } + `) + replacement = replacement.declarations[0].init.properties[0] + replacement.value.body = path.node.body + replacement.value.params = path.node.params + path.replaceWith(replacement) + }, + Function (path) { + if ( + path.type != 'FunctionDeclaration' && + !path.node.scoperWrapped && + !path.node.body.scoperWrapped + ) { + path.node.scoperWrapped = true + path.node.body.scoperWrapped = true + let uuid = getPathUUID({ path }) + let replacement = functionWrapper(uuid, path, aster) + path.replaceWith(replacement) + } + }, + FunctionDeclaration (path) { + if (!path.node.scoped) { + path.node.scoped = true + const parentBlock = path.scope.parent + try { + parentBlock.block.body.forEach(node => { + if (node.lastContextNode) { + let uuid = getPathUUID({ path }) + let newNode = aster(/*javascript*/ ` + ${uuid}.$functionScoper(${path.node.id.name}) + `) + node.body.splice(1, 0, newNode) + throw new Error('break foreach') + } + }) + } catch (err) { + // nothing + } + } + }, + VariableDeclarator (path) { + if (!path.node.inScope) { + path.node.inScope = true + let parentPath = getsmart.bind(this)(path, 'parentPath', undefined) + if ( + // this is for inline let and const declarations in normal + // js blocks + (parentPath.node.kind == 'let' || parentPath.node.kind == 'const') && + // we check the length of declarations because we only have to do inline replacement + // if there's a chance another declaration might use a former one + parentPath.node.declarations.length > 1 && + !( + parentPath.parentPath.node.type == 'ForInStatement' || + parentPath.parentPath.node.type == 'ForOfStatement' || + parentPath.parentPath.node.type == 'ForStatement' + ) + ) { + let uuid = getPathUUID({ path }) + if (uuid) { + let indexInParent = parentPath.node.declarations.indexOf(path.node) + let newDeclaration = scopeVar({ + aster, + inline: true, + uuid, + key: parentPath.node.declarations[indexInParent].id.name, + type: parentPath.node.kind + }) + parentPath.node.declarations.splice( + indexInParent + 1, + 0, + newDeclaration + ) + } + } else if ( + // + (parentPath.node.kind == 'let' || + parentPath.node.kind == 'var' || + parentPath.node.kind == 'const') && + // only do this for singular declarations + parentPath.node.declarations.length < 2 && + // and check if variable is declared inside a ForX statement + (parentPath.parentPath.node.type == 'ForInStatement' || + parentPath.parentPath.node.type == 'ForOfStatement' || + parentPath.parentPath.node.type == 'ForStatement') + ) { + let uuid = getPathUUID({ path }) + if (uuid) { + let indexInParent = parentPath.node.declarations.indexOf(path.node) + let newNode = scopeVar({ + aster, + uuid, + key: parentPath.node.declarations[indexInParent].id.name, + type: parentPath.node.kind + }) + parentPath.parentPath.node.body.body.splice(0, 0, newNode) + } + } else if ( + // this is a special case for when ForStatements get their own scope + (parentPath.node.kind == 'let' || parentPath.node.kind == 'const') && + // we check the length of declarations because we only have to do inline replacement + // if there's a chance another declaration might use a former one + parentPath.node.declarations.length > 1 && + parentPath.parentPath.node.type == 'ForStatement' + ) { + // if the first declaration isn't our context declaration, insert one + let uuid = gosmart.bind(this)(path, 'scope.uuid', jsUUID()) + if (!parentPath.node.declarations[0].contextDeclaration) { + let inlineContextDeclaration = createInlineContext({ + path, + uuid, + aster + }) + parentPath.node.declarations.splice(0, 0, inlineContextDeclaration) + } + if (uuid) { + let indexInParent = parentPath.node.declarations.indexOf(path.node) + let newDeclaration = scopeVar({ + aster, + inline: true, + uuid, + key: parentPath.node.declarations[indexInParent].id.name, + type: parentPath.node.kind + }) + parentPath.node.declarations.splice( + indexInParent + 1, + 0, + newDeclaration + ) + } + } else if ( + parentPath.node.kind == 'let' || + parentPath.node.kind == 'const' + ) { + let uuid = getPathUUID({ path }) + if (uuid) { + let indexInParent = parentPath.node.declarations.indexOf(path.node) + let newNode = scopeVar({ + aster, + uuid, + key: parentPath.node.declarations[indexInParent].id.name, + type: parentPath.node.kind + }) + parentPath.insertAfter(newNode) + } + } else { + // let uuid = getPathUUID({path}) + // if(uuid){ + // let indexInParent = parentPath.node.declarations.indexOf(path.node) + // let newNode = scopeVar({ + // aster, + // uuid, + // key: parentPath.node.declarations[indexInParent].id.name, + // type: parentPath.node.kind + // }) + // parentPath.insertAfter(newNode) + // } + } + } + } + } + let ret = { + visitor: metaVisitor + // visitor: { + // Program(path){ + // path.traverse(metaVisitor) + // } + // } + } + return ret +} +export const transform = (src, opts = {}) => { + return getBabel().transform(src, { + plugins: [babelPlugin], + ...opts + }) +} +/** non-parser stuff */ +export const stripUuids = (thing, seen = []) => { + try { + delete thing.uuid + } catch { + // nothing + } + if (typeof thing === 'object') { + const keys = Object.keys(thing) + for (const key of keys) { + const val = thing[key] + if (!seen.includes(val)) { + seen.push(val) + stripUuids(val, seen) + } + } + } +} +export const dupe = (obj, opts = {}) => { + return parse(stringify(obj, opts), opts) +} +export const clone = (obj, opts = {}) => { + return dupe(obj, opts) +} +export const schema = (obj1, obj2, opts = {}) => { + if (!opts.noSchemaClone) { + obj2 = clone(obj2, opts) + } + return merge(obj1, obj2, { + ...opts + }) +} +export const create = (obj1, obj2, opts) => { + let ret = merge(obj1, obj2, { + clone: true, + ...opts + }) + + return ret +} +export const merge = (value1, value2, opts = {}, seen = new Map()) => { + if (seen.has(value1)) return seen.get(value1) + + if (value1 instanceof Array && value2 instanceof Array) { + return value1 + } + + // base case non-basic value + if (basic(value1) && !opts.overwrite) { + return value1 + } + + if (opts.overwrite && basic(value2)) { + return value2 + } + + if (!basic(value1) && basic(value2)) { + return value1 + } + + if (opts.clone) { + value1 = clone(value1) + value2 = clone(value2) + } + + let props = Object.keys(value2) + + props.forEach(prop => { + let propertyValue1 = value1[prop] + if (prop in value1 && basic(propertyValue1) && !opts.overwrite) { + return + } + let propertyValue2 = value2[prop] + seen.set(value1, value1) + let newVal = propertyValue2 + if (prop in value1) { + newVal = merge.bind(this)( + propertyValue1, + propertyValue2, + { ...opts, ...{ clone: false } }, + seen + ) + } + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + value1 + ) { + const setToUse = this.$set || local.vue.Vue.set + setToUse?.(value1, prop, newVal) + if ( + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + value1[prop] = newVal + if ( + getsmart.bind(this)(local.vue, 'store', false) && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + }) + + return value1 +} +export const basic = value => { + let valueType = typeof value + let ret = + !( + valueType == 'object' || + valueType == 'array' || + valueType == 'function' + ) || value === null + return ret +} +export const mod = (args, mod) => { + return mod(args) || args +} +// transform(value, fn, path, ret={}){ +// return forEach(value, fn, path, ret) +// }, +export const deepForEach = ( + value, + fn, + path, + ret = {}, + seens = { originals: [], clones: [] }, + first = true +) => { + path = path || '' + if (first) { + value = { '': value } + } + // if(!(typeof value == 'string' || typeof value == 'boolean' || typeof value == 'number')){ + // seens.originals.push(value) + // } + if (Array.isArray(value)) { + forEachArray(value, fn, path, ret, seens) + } else if (typeof value == 'object') { + forEachObject(value, fn, path, ret, seens) + } + return ret[''] +} +export const forEachObject = (obj, fn, path, ret, seens) => { + for (const key in obj) { + const deepPath = path ? `${path}.${key}` : key + let primitive = + typeof obj[key] == 'string' || + typeof obj[key] == 'boolean' || + typeof obj[key] == 'number' + if (primitive || seens.originals.indexOf(obj[key]) < 0) { + if (!primitive) { + seens.originals.push(obj[key]) + } + // Note that we always use obj[key] because it might be mutated by forEach + fn(obj[key], key, obj, deepPath, ret, seens) + + deepForEach(obj[key], fn, deepPath, ret, seens, false) + } + } +} +export const forEachArray = (array, fn, path, ret = {}, seens) => { + array.forEach((value, index, arr) => { + let primitive = + typeof value == 'string' || + typeof value == 'boolean' || + typeof value == 'number' + if (primitive || seens.originals.indexOf(value) < 0) { + if (!primitive) { + seens.originals.push(value) + } + const deepPath = `${path}.${index}` + + fn(value, index, arr, deepPath, ret, seens) + + // Note that we use arr[index] because it might be mutated by forEach + deepForEach(arr[index], fn, deepPath, ret, seens, false) + } + }) +} +export const setThing = ({ + option, + list = getsmart.bind(this)(objList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype, + push, + strings, + targets +} = {}) => { + let index = thingIndex({ + option, + list, + obj, + keys, + keymatchtype, + strings + }) + if (obj == 'debug') { + console.log('index') + console.log(index) + console.log('list') + console.log(list) + } + if (index >= 0 && list) { + if (targets && targets.length && typeof targets.length == 'number') { + for (var i = 0; i < targets.length; i++) { + let value = getsmart.bind(this)(option, targets[i], undefined) + if (value) { + setsmart.bind(this)(list[index], targets[i], value) + } + } + } else { + list.splice(index, 1, option) + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) + ) { + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else if ( + getsmart.bind(this)(local.vue, 'store', false) && + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + // list[index] = option + } else if (push && list) { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) || + getsmart.bind(this)(local.vue, 'store', false) + ) { + list.splice(list.length, 0, option) + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + list.push(option) + } + index = list.length - 1 + } + return index +} +export const setThings = ({ + options, + list = getsmart.bind(this)(objList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype, + push, + async +} = {}) => { + if (options && options instanceof Array && list) { + for (let option of options) { + if (async) { + new Promise(() => { + setThing({ + option, + list, + obj, + keys, + keymatchtype, + push + }) + }) + } else { + setThing({ + option, + list, + obj, + keys, + keymatchtype, + push + }) + } + } + } + return list +} +export const optIn = ( + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype, + index +) => { + if (typeof option === 'object') { + obj = true + } + if (!obj && list && list.indexOf && list.indexOf(option) >= 0) { + return index ? list.indexOf(option) : true + } else if (obj && list && typeof list.length == 'number') { + for (var i = 0; i < list.length; i++) { + if (!(keys && typeof keys.length == 'number')) return + for (var indKey = 0; indKey < keys.length; indKey++) { + if (keymatchtype == 'broad') { + if ( + list[i] && + getsmart.bind(this)(list[i], keys[indKey], undefined) == + getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(list[i], keys[indKey], undefined) !== undefined + ) { + return index ? i : true + } else if ( + list[i] && + typeof list[i] == 'string' && + list[i] == getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(option, keys[indKey], undefined) !== undefined + ) { + return index ? i : true + } + } else { + if ( + list[i] && + getsmart.bind(this)(list[i], keys[indKey], undefined) == + getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(list[i], keys[indKey], undefined) !== undefined + ) { + if (indKey == keys.length - 1) { + return index ? i : true + } + } else if ( + list[i] && + typeof list[i] == 'string' && + list[i] == getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(option, keys[indKey], undefined) !== undefined + ) { + if (indKey == keys.length - 1) { + return index ? i : true + } + } + } + } + } + } + return index ? -1 : false +} +export const thingIn = ({ + option, + list = getsmart.bind(this)(objList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype, + retIndex + // vue = local.vue +} = {}) => { + if (typeof option === 'object') { + obj = true + } + if (!obj && list && list.indexOf && list.indexOf(option) >= 0) { + if (retIndex) { + return list.indexOf(option) + } else { + return true + } + } else if (obj && list && typeof list.length == 'number') { + for (var i = 0; i < list.length; i++) { + if (!(keys && typeof keys.length == 'number')) return + for (var indKey = 0; indKey < keys.length; indKey++) { + if (keymatchtype == 'broad') { + if ( + list[i] && + getsmart.bind(this)(list[i], keys[indKey], undefined) == + getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(list[i], keys[indKey], undefined) !== undefined + ) { + if (retIndex) { + return i + } else { + return true + } + } else if ( + list[i] && + typeof list[i] == 'string' && + list[i] == getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(option, keys[indKey], undefined) !== undefined + ) { + if (retIndex) { + return i + } else { + return true + } + } + } else { + if ( + list[i] && + getsmart.bind(this)(list[i], keys[indKey], undefined) == + getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(list[i], keys[indKey], undefined) !== undefined + ) { + if (indKey == keys.length - 1) { + if (retIndex) { + return i + } else { + return true + } + } + } else if ( + list[i] && + typeof list[i] == 'string' && + list[i] == getsmart.bind(this)(option, keys[indKey], undefined) && + getsmart.bind(this)(option, keys[indKey], undefined) !== undefined + ) { + if (indKey == keys.length - 1) { + if (retIndex) { + return i + } else { + return true + } + } + } + } + } + } + } + if (retIndex) { + return -1 + } else { + return false + } +} +export const optsIn = ( + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (!(options instanceof Array)) return true + for (let option of options) { + // if(typeof option === 'object'){ + // obj = true + // } + if (!obj && list && list.indexOf && list.indexOf(option) >= 0) { + // return true + } else if (obj && list) { + for (var i = 0; i < list.length; i++) { + if (!optIn(option, list[i], obj, keys, keymatchtype)) { + return false + } + } + } else { + return false + } + } + return true +} +export const thingsIn = ({ + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if (!(options instanceof Array)) return true + for (let option of options) { + // if(typeof option === 'object'){ + // obj = true + // } + if (!obj && list && list.indexOf && list.indexOf(option) >= 0) { + // return true + } else if (obj && list && typeof list.length == 'number') { + for (var i = 0; i < list.length; i++) { + if (!optIn(option, list[i], obj, keys, keymatchtype)) { + return false + } + } + } else { + return false + } + } + return true +} +export const anyOptsIn = ( + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (!(options instanceof Array)) return false + for (let option of options) { + // if(typeof option === 'object'){ + // obj = true + // } + if (!obj && list && list.indexOf && list.indexOf(option) >= 0) { + return true + } else if (obj && list && typeof list.length == 'number') { + for (var i = 0; i < list.length; i++) { + if (optIn(option, list[i], obj, keys, keymatchtype)) { + return true + } + } + } + } + return false +} +export const anyThingsIn = ({ + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if (!(options instanceof Array)) return false + for (let option of options) { + // if(typeof option === 'object'){ + // obj = true + // } + if (!obj && list && list.indexOf && list.indexOf(option) >= 0) { + return true + } else if (obj && list && typeof list.length == 'number') { + for (var i = 0; i < list.length; i++) { + if (optIn(option, list[i], obj, keys, keymatchtype)) { + return true + } + } + } + } + return false +} +export const optIndex = ( + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (typeof option === 'object') { + obj = true + } + if (obj && list && keys && typeof list.length == 'number') { + for (var i = 0; i < list.length; i++) { + if (optIn(option, list, obj, keys, keymatchtype)) { + return i + } + } + } else if (list) { + return list.indexOf(option) + } + return -1 +} +export const thingIndex = ({ + option, + list, + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype, + strings +} = {}) => { + if (typeof option === 'object') { + obj = true + } + if (obj && list && keys) { + let index = thingIn({ + option, + list, + obj, + keys, + keymatchtype, + strings, + retIndex: true + }) + return index + } else if (list) { + return list.indexOf(option) + } + return -1 +} +export const pushOpt = ( + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype, + index +) => { + if ( + typeof list == 'object' && + !optIn(option, list, obj, keys, keymatchtype) + ) { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) || + getsmart.bind(this)(local.vue, 'store', false) + ) { + list.splice(list.length, 0, option) + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + list.push(option) + } + } + return index + ? optIn(option, list, obj, keys, keymatchtype, index) + : optIn(option, list, obj, keys, keymatchtype, index) +} +export const addOpt = ( + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype, + index +) => { + if (typeof list == 'object') { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) || + getsmart.bind(this)(local.vue, 'store', false) + ) { + list.splice(list.length, 0, option) + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + list.push(option) + } + } + return index + ? optIn(option, list, obj, keys, keymatchtype, index) + : optIn(option, list, obj, keys, keymatchtype, index) +} +export const pushThing = ({ + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if ( + typeof list == 'object' && + !thingIn({ option, list, obj, keys, keymatchtype }) + ) { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) || + getsmart.bind(this)(local.vue, 'store', false) + ) { + list.splice(list.length, 0, option) + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + list.push(option) + } + } +} +export const pushOpts = ( + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (!(options instanceof Array)) return + for (let option of options) { + pushOpt(option, list, obj, keys, keymatchtype) + } +} +export const pushThings = ({ + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if (!(options instanceof Array)) return + for (let option of options) { + pushThing({ option, list, obj, keys, keymatchtype }) + } +} +export const popOpt = ( + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (typeof list == 'object' && optIn(option, list, obj, keys, keymatchtype)) { + list.splice(optIndex(option, list, obj, keys, keymatchtype), 1) + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) || + getsmart.bind(this)(local.vue, 'store', false) + ) { + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + } +} +export const popThing = ({ + option, + list = getsmart.bind(this)(stringList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if ( + typeof list == 'object' && + thingIn({ + option, + list, + obj, + keys, + keymatchtype + }) + ) { + list.splice( + thingIndex({ + option, + list, + obj, + keys, + keymatchtype + }), + 1 + ) + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) || + getsmart.bind(this)(local.vue, 'store', false) + ) { + if ( + !localStorage.getItem('vuexWriteLock') && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + } +} +export const popOpts = ( + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (!(options instanceof Array)) return + for (let option of options) { + popOpt(option, list, obj, keys, keymatchtype) + } +} +export const popThings = ({ + options, + list = getsmart.bind(this)(stringList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if (!(options instanceof Array)) return + for (let option of options) { + popOpt(option, list, obj, keys, keymatchtype) + } +} +export const toggleOpt = ( + option, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (optIn(option, list, obj, keys, keymatchtype)) { + popOpt(option, list, obj, keys, keymatchtype) + } else { + pushOpt(option, list, obj, keys, keymatchtype) + } +} +export const toggleThing = ({ + option, + list = getsmart.bind(this)(stringList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if (optIn(option, list, obj, keys, keymatchtype)) { + popOpt(option, list, obj, keys, keymatchtype) + } else { + pushOpt(option, list, obj, keys, keymatchtype) + } +} +export const toggleOpts = ( + options, + list = getsmart.bind(this)(stringList), + obj, + keys = ['uuid', '_id', 'id'], + keymatchtype +) => { + if (!(options instanceof Array)) return + for (let option in options) { + toggleOpt(option, list, obj, keys, keymatchtype) + } +} +export const toggleThings = ({ + options, + list = getsmart.bind(this)(stringList), + obj = true, + keys = ['uuid', '_id', 'id'], + keymatchtype +} = {}) => { + if (!(options instanceof Array)) return + for (let option in options) { + if (optIn(option, list, obj, keys, keymatchtype)) { + popOpt(option, list, obj, keys, keymatchtype) + } else { + pushOpt(option, list, obj, keys, keymatchtype) + } + } +} +// no use right now +// export const ratchetOpt = ( +// option, +// list, +// obj, +// keys = ['uuid', '_id', 'id'], +// keymatchtype +// ) => { +// // find(obj, property, equals){ +// // if(getsmart.bind(this)(obj, 'constructor', undefined) == Array){ +// // for(var i=0; i { + if (!property && obj && typeof obj == 'string') { + property = obj.split('.') + try { + obj = eval(property[0]) + } catch (err) { + // console.error(err) + + obj = property[0] + } + property = property.slice(1, property.length) + } + if (!property) { + if (context) { + return { + value: defaultValue, + undefined: true + } + } else { + return defaultValue + } + } + // If the property list is in dot notation, convert to array + if (typeof property == 'string') { + property = parsePropertyPath(property) + } else if (getsmart.bind(this)(property, 'constructor', false) !== Array) { + if (context) { + return { + value: defaultValue, + undefined: true, + err: 'properties path @property argument was not passed properly' + } + } else { + return defaultValue + } + } + + let deepGetByArray = deepGetByArrayUnbound.bind(this) + + return deepGetByArray(obj, property, defaultValue) + + // In order to avoid constantly checking the type of the property + // we separate the real logic out into an inner function. + function deepGetByArrayUnbound (obj, propsArray, defaultValue) { + // This case getting to the last property but it not being ultimately defined + // Not just having a value of undefined + if ( + propsArray.length > 0 && + context && + typeof obj == 'object' && + obj !== null && + !(ee(propsArray[0]) in obj) + ) { + return { + value: defaultValue, + undefined: true + } + } + + // If we have reached an undefined/null property + // then stop executing and return the default value. + // If no default was provided it will be undefined. + if ( + typeof obj == 'undefined' || + obj == null || + (schema && obj.constructor.name !== schema) + ) { + if (context) { + let undef = true + if (propsArray.length === 0) { + undef = false + } + return { + value: defaultValue, + undefined: undef, + schema: schema && obj.constructor.name === schema + } + } else { + return defaultValue + } + } // If the path array has no more elements, we've reached + // the intended property and return its value + + if (propsArray.length === 0) { + if (context) { + return { + value: obj, + undefined: false + } + } else { + return obj + } + } // Prepare our found property and path array for recursion + + var nextObj = obj[ee(propsArray[0])] + var remainingProps = propsArray.slice(1) + return deepGetByArray(nextObj, remainingProps, defaultValue) + } +} +export const escapePropertyPath = (path = '') => { + let newPath = escapeEscapes(path) + return '["' + newPath + '"]' +} +export const epp = (path = '') => { + return escapePropertyPath(path) +} +export const escapeEscapes = (path = '') => { + let newPath = '' + for (let i in path) { + i = +i + let char = path[i] + if (i > 0 && i < path.length - 1) { + let prevChar = path[i - 1] + let nextChar = path[i + 1] + let openingArrayPath = char === '"' && prevChar === '[' + // && (nextChar !== "\\" || i === path.length-1) + let closingArrayPath = + char === '"' && nextChar === ']' && prevChar !== '\\' + // let offset = 0 + // if(openingArrayPath) offset = 1 + if (openingArrayPath || closingArrayPath) { + newPath += '\\' + // path = path.slice(0,i+offset)+"\\"+path.slice(i+offset,path.length) + } + } + newPath += char + } + return newPath +} +export const ee = (path = '') => { + return escapeEscapes(path) +} +// TODO +// Make parsing use \" or \' +// Currently only uses \" +export const parsePropertyPath = (path = '') => { + let array = [] + + let readingArrayBasedPath = false + let i = 0 + let push = false + let pushed = false + while (i < path.length) { + let arrayPathStart = path[i] == '[' && path[i + 1] == '"' + let escapedStart = !(path[i + 1] !== '\\' || i === 0) + + if (readingArrayBasedPath) { + // we found the end of an array delimited path + let arrayPathEnd = path[i] == '"' && path[i + 1] == ']' + let escapedEnd = !(path[i - 1] !== '\\' || i == 0) + if (arrayPathEnd && !escapedEnd) { + i += 1 + readingArrayBasedPath = false + if (!pushed) push = true + } else { + // if the path includes an "escaped" array based path begin or end value + // do not push the escape character + if ( + (path[i] == '\\' && path[i + 1] == '"' && path[i + 2] == ']') || + (path[i - 1] == '[' && path[i] == '\\' && path[i + 1] == '"') + ) { + // nothing + } else { + array[array.length - 1] += path[i] + } + } + } else if (path[i] == '.') { + if (!pushed) push = true + } + // we found the start of an array delimited path + else if (arrayPathStart && !escapedStart) { + readingArrayBasedPath = true + if (!pushed) push = true + i += 1 + } else { + if (i == 0) array.push('') + array[array.length - 1] += path[i] + } + + i++ + if (push && i < path.length) { + pushed = true + array.push('') + push = false + } else { + pushed = false + } + } + + return array +} +export const ppp = (path = '') => { + return this.parsePropertyPath(path) +} +export const parsePropertyArray = pathArray => { + let path = '' + + if (pathArray instanceof Array) { + pathArray.forEach(subPath => { + path += epp(subPath) + }) + } else if (typeof pathArray === 'string') { + return path + } + + return path +} +export const ppa = pathArray => { + return this.parsePropertyArray(pathArray) +} +export const pathToArray = path => { + if (typeof path == 'string') { + return parsePropertyPath(path) + } else { + return path + } +} +export const pathToString = path => { + if (typeof path == 'string') { + let ret = parsePropertyPath(path) + ret = parsePropertyArray(ret) + return ret + } else { + let ret = parsePropertyArray(path) + return ret + } +} +export const setsmart = (obj, property, value, context?: any) => { + if (!property && typeof obj == 'string') { + property = obj.split('.') + try { + obj = eval(property[0]) + } catch (err) { + obj = property[0] + } + property = property.slice(1, property.length) + } + // If the property list is in dot notation, convert to array + if (typeof property == 'string') { + property = parsePropertyPath(property) + } else if (getsmart.bind(this)(property, 'constructor', false) !== Array) { + if (context) { + return { + value: value, + undefined: true, + err: 'properties path @property argument was not passed properly' + } + } else { + return value + } + } + + // if no obj make obj + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) obj = {} + + let deepSetByArray = deepSetByArrayUnbound.bind(this) + + if (property) { + return deepSetByArray(obj, property, value) + } else { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + obj + ) { + const setToUse = this.$set || local.vue.Vue.set + setToUse(obj, undefined, value) + if ( + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + obj = value + if ( + getsmart.bind(this)(local.vue, 'store', false) && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + if (context) { + return { + value: obj, + undefined: false, + err: 'there were no properties passed' + } + } else { + return obj + } + } + + // In order to avoid constantly checking the type of the property + // we separate the real logic out into an inner function. + function deepSetByArrayUnbound (obj, propsArray, value) { + // If the path array has only 1 more element, we've reached + // the intended property and set its value + if (propsArray.length == 1) { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + obj + ) { + const setToUse = this.$set || local.vue.Vue.set + setToUse(obj, ee(propsArray[0]), value) + if ( + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + // TODO: make parent object new object so that react can see the change + obj[ee(propsArray[0])] = value + if ( + getsmart.bind(this)(local.vue, 'store', false) && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + if (context) { + return { + value: obj[ee(propsArray[0])], + undefined: false + } + } else { + return obj[ee(propsArray[0])] + } + } + // Prepare our path array for recursion + var remainingProps = propsArray.slice(1) + // check if next prop is object + if (typeof obj[ee(propsArray[0])] !== 'object') { + // If we have reached an undefined/null property + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + obj + ) { + const setToUse = this.$set || local.vue.Vue.set + setToUse(obj, ee(propsArray[0]), {}) + if ( + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + obj[ee(propsArray[0])] = {} + if ( + getsmart.bind(this)(local.vue, 'store', false) && + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } + } + return deepSetByArray(obj[ee(propsArray[0])], remainingProps, value) + } +} +export const deletesmart = (obj, property) => { + if (!property && typeof obj == 'string') { + property = obj.split('.') + try { + obj = eval(property[0]) + } catch (err) { + // console.error(err) + obj = property[0] + } + property = property.slice(1, property.length) + } + // If the property list is in dot notation, convert to array + if (typeof property == 'string') { + property = parsePropertyPath(property) + } + let parentPathArray = property.slice(0, property.length - 1) + let path = property[property.length - 1] + let parentObj = getsmart(obj, parentPathArray, {}) + + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + obj + ) { + this.$delete(parentObj, path) + } else { + delete parentObj[path] + } +} +export const pushSmart = (array, value) => { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + array + ) { + array.push(value) + if ( + typeof getsmart.bind(this)(window, '$store.commit', undefined) == + 'function' + ) { + window.$store.commit(local.vue.basePath || 'graph/thing') + } + } else { + array.push(value) + } +} +export const gosmart = (obj, property, value, context, schema) => { + // stands for get or set smart + var get = getsmart.bind(this)( + obj, + property, + value, + true, + schema ? absoluteType.bind(this)(value) : false + ) + if (get.undefined || (schema && get.schema === false)) { + get = setsmart.bind(this)(obj, property, get.value, context) + if (context) { + return get + } else { + return get + } + } else { + return get.value + } +} +export const gosmarter = (obj, property, value, context, schema = true) => { + return gosmart.bind(this)(obj, property, value, context, schema) +} +export const absoluteType = value => { + let type + try { + type = value.constructor.name + } catch (e) { + if (typeof value === 'undefined') type = 'undefined' + if (value === null) type = 'null' + } + return type +} +export const vgosmart = (obj, property, value, context) => { + // stands for v-model get or set smart + // return value from property path, either gotten or smartly set + return { + get: () => { + var get = getsmart.bind(this)(obj, property, value, true) + if (get.undefined) { + get = setsmart.bind(this)(obj, property, get.value, context) + } + if (context) { + return get + } else { + return getsmart.bind(this)(get, 'value', get) + } + }, + set: val => { + setsmart.bind(this)(obj, property, val) + } + } +} +export const getsmartval = (obj, property, defaultValue) => { + // get the value of a property path based off its type + let target = getsmart.bind(this)(obj, property, defaultValue) + if (target && target.type) { + if (target[target.type]) { + return target[target.type] + } else { + return defaultValue + } + } else if (target) { + return target + } + return defaultValue +} +export const safestring = something => { + return smarts.stringify(something || '') +} +export const safeparse = something => { + return smarts.parse(something || '') +} +export const flatten = (arrays, func = i => i) => { + const flat = [] + + arrays.forEach(array => { + if (Array.isArray(array)) { + flat.push(...flatten(array)) + } else { + flat.push(func(array)) + } + }) + + return flat +} +export const mapsmart = (list, keyProperty = 'title', returnExistant) => { + return new Promise((resolve, reject) => { + if (!keyProperty) { + reject() + } else if (list && typeof list.length == 'number') { + if (list.length == 0) { + if ( + (returnExistant && + getsmart.bind(this)(list, 'mapped.' + returnExistant, false)) || + !returnExistant + ) { + resolve(true) + } else if (returnExistant) { + resolve(false) + } else { + resolve() + } + } + if (!list.mapped || typeof list.mapped === 'boolean') { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + list + ) { + const setToUse = this.$set || local.vue.Vue.set + setToUse(list, 'mapped', {}) + } else { + list['mapped'] = {} + } + } + for (var i = 0; i < list.length; i++) { + if (typeof list[i] !== 'string') { + if ( + getsmart.bind(this)(local.vue, 'reactiveSetter', false) && + getsmart.bind(this)( + this, + '$set', + getsmart.bind(this)(local.vue, 'Vue.set', false) + ) && + list.mapped + ) { + const setToUse = this.$set || local.vue.Vue.set + setToUse(list.mapped, list[i][keyProperty], list[i]) + } else { + list['mapped'][list[i][keyProperty]] = list[i] + } + if (i == list.length - 1) { + if ( + (returnExistant && + getsmart.bind(this)(list, 'mapped.' + returnExistant, false)) || + !returnExistant + ) { + resolve(true) + } else if (returnExistant) { + resolve(false) + } else { + resolve() + } + } + } + // else if(populate){ + // var funCounter = this.funCounter + // this.funCounter = this.funCounter + 1 + // getThing({ + // thing: list[i], + // clientId: this._uid, + // funCounter + // }) + // this.$options.sockets['giveThing'] = data => { + // if(this._uid == data.clientId && data.funCounter == funCounter){ + // (this.$set || local.vue.Vue.set)(list, i.toString(), data.thing) + // (this.$set || local.vue.Vue.set)(list.mapped, list[i][keyProperty], list[i]) + // } + // if(i==list.length-1){ + // if((returnExistant && getsmart.bind(this)(list, 'mapped.'+returnExistant, false)) || !returnExistant){ + // resolve(true) + // } else if(returnExistant) { + // resolve(false) + // } else { + // resolve() + // } + // } + // } + // } + else if (i == list.length - 1) { + if ( + (returnExistant && + getsmart.bind(this)(list, 'mapped.' + returnExistant, false)) || + !returnExistant + ) { + resolve(true) + } else if (returnExistant) { + resolve(false) + } else { + resolve() + } + } + } + // if(list.mapped && !list.mapped['agora-client-mapped']){ + // (this.$set || local.vue.Vue.set)(list.mapped, 'agora-client-mapped', true) + // } + } + }) +} +export const domval = thing => { + return getsmart.bind(this)(thing, 'properties.description', '') +} +export const getParent = (levels = Infinity) => { + if (typeof levels == 'string') levels = (levels.match(/\.\./g) || []).length + + if (levels >= this.pathAsArray.length - 1) { + return this.pathAsArray[0] + } + + let level = this.pathAsArray.length - 1 - levels + + return this.pathAsArray[level] +} +export const getThing = (props = {}) => { + const { list = getsmart.bind(this)(objList), defaultValue = undefined } = + props + + var index = thingIn({ + ...props, + retIndex: true + }) + if (index >= 0) { + return list[index] + } else { + return defaultValue + } +} +export const equal = (obj1, obj2, seen = []) => { + if (obj1 && obj2 && typeof obj1 == 'object' && typeof obj2 == 'object') { + seen.push(obj1, obj2) + //Loop through properties in object 1 + for (const p in obj1) { + //Check property exists on both objects + if ( + typeof obj1.hasOwnProperty == 'function' && + typeof obj2.hasOwnProperty == 'function' && + Object.prototype.hasOwnProperty.call(obj1, p) !== + Object.prototype.hasOwnProperty.call(obj2, p) + ) + return false + + switch (typeof obj1[p]) { + //Deep compare objects + case 'object': + if (seen.indexOf(obj1[p]) < 0 && !equal(obj1[p], obj2[p], seen)) + return false + break + //Compare function code + case 'function': + if ( + typeof obj2[p] == 'undefined' || + obj1[p].toString() != obj2[p].toString() + ) + return false + break + //Compare values + default: + if (obj1[p] != obj2[p]) return false + } + } + + //Check object 2 for any extra properties + for (const p in obj2) { + if (!(p in obj1)) return false + } + return true + } +} +export const mergeall = (array, options) => { + if (!Array.isArray(array)) { + throw new Error('first argument should be an array') + } + + return array.reduce(function (prev, next) { + return merge(prev, next, options) + }, {}) +} + +// export const smarts with all other exports +export const smarts = { + local, + t, + getBabel, + uuid, + pause, + save, + toJavascript, + toJavascriptAux, + createObjectProperties, + serialize, + stringify, + replacer, + setKnown, + stringifier, + primitives, + Primitives, + play, + load, + parse, + parser, + revive, + createScopedEval, + defineVariable, + scopedEval, + jsUUID, + context, + contextObject, + createContext, + createInlineContext, + addBindingsToContext, + scopeVarCode, + scopeVarInlineCode, + scopeVar, + functionWrapper, + bodyInsert, + initBlock, + getNodeUUID, + getPathUUID, + babelPlugin, + transform, + stripUuids, + dupe, + clone, + schema, + create, + merge, + basic, + mod, + deepForEach, + forEachObject, + forEachArray, + setThing, + setThings, + optIn, + thingIn, + optsIn, + thingsIn, + anyOptsIn, + anyThingsIn, + optIndex, + thingIndex, + pushOpt, + addOpt, + pushThing, + pushOpts, + pushThings, + popOpt, + popThing, + popOpts, + popThings, + toggleOpt, + toggleThing, + toggleOpts, + toggleThings, + // ratchetOpt, + getsmart, + escapePropertyPath, + epp, + escapeEscapes, + ee, + parsePropertyPath, + ppp, + parsePropertyArray, + ppa, + pathToArray, + pathToString, + setsmart, + deletesmart, + pushSmart, + gosmart, + gosmarter, + absoluteType, + vgosmart, + getsmartval, + safestring, + safeparse, + flatten, + mapsmart, + domval, + getParent, + getThing, + equal, + mergeall +} diff --git a/remix/package.json b/remix/package.json index a748850..d14cf7e 100644 --- a/remix/package.json +++ b/remix/package.json @@ -6,6 +6,13 @@ "dev": "remix dev --port 9999" }, "dependencies": { + "@babel/core": "^7.14.8", + "@babel/generator": "^7.8.4", + "@babel/parser": "^7.22.5", + "@babel/polyfill": "^7.4.4", + "@babel/standalone": "^7.14.8", + "@babel/template": "^7.14.8", + "@babel/types": "^7.15.0", "@chakra-ui/react": "^2.7.1", "@remix-run/node": "^1.15.0", "@remix-run/react": "^1.15.0", @@ -13,8 +20,11 @@ "@vercel/analytics": "^0.1.11", "@vercel/remix": "^1.15.0", "isbot": "latest", + "lodash-es": "^4.17.21", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "smarts": "^2.0.3", + "uuid": "^9.0.0" }, "devDependencies": { "@remix-run/dev": "^1.15.0", diff --git a/remix/pnpm-lock.yaml b/remix/pnpm-lock.yaml index 36703fd..ff766bb 100644 --- a/remix/pnpm-lock.yaml +++ b/remix/pnpm-lock.yaml @@ -1,10 +1,31 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false dependencies: + '@babel/core': + specifier: ^7.14.8 + version: 7.20.12 + '@babel/generator': + specifier: ^7.8.4 + version: 7.20.14 + '@babel/parser': + specifier: ^7.22.5 + version: 7.22.5 + '@babel/polyfill': + specifier: ^7.4.4 + version: 7.12.1 + '@babel/standalone': + specifier: ^7.14.8 + version: 7.22.5 + '@babel/template': + specifier: ^7.14.8 + version: 7.20.7 + '@babel/types': + specifier: ^7.15.0 + version: 7.20.7 '@chakra-ui/react': specifier: ^2.7.1 version: 2.7.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.0.28)(framer-motion@10.12.17)(react-dom@18.2.0)(react@18.2.0) @@ -26,12 +47,21 @@ dependencies: isbot: specifier: latest version: 3.6.12 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 react: specifier: ^18.2.0 version: 18.2.0 react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + smarts: + specifier: ^2.0.3 + version: 2.0.3 + uuid: + specifier: ^9.0.0 + version: 9.0.0 devDependencies: '@remix-run/dev': @@ -61,7 +91,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 - dev: true /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} @@ -72,7 +101,6 @@ packages: /@babel/compat-data@7.20.14: resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==} engines: {node: '>=6.9.0'} - dev: true /@babel/core@7.20.12: resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==} @@ -84,7 +112,7 @@ packages: '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.20.12) '@babel/helper-module-transforms': 7.20.11 '@babel/helpers': 7.20.13 - '@babel/parser': 7.20.15 + '@babel/parser': 7.22.5 '@babel/template': 7.20.7 '@babel/traverse': 7.20.13 '@babel/types': 7.20.7 @@ -95,7 +123,6 @@ packages: semver: 6.3.0 transitivePeerDependencies: - supports-color - dev: true /@babel/eslint-parser@7.19.1(@babel/core@7.20.12)(eslint@8.34.0): resolution: {integrity: sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==} @@ -118,7 +145,6 @@ packages: '@babel/types': 7.20.7 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 - dev: true /@babel/helper-annotate-as-pure@7.18.6: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} @@ -147,7 +173,6 @@ packages: browserslist: 4.21.5 lru-cache: 5.1.1 semver: 6.3.0 - dev: true /@babel/helper-create-class-features-plugin@7.20.12(@babel/core@7.20.12): resolution: {integrity: sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==} @@ -198,7 +223,6 @@ packages: /@babel/helper-environment-visitor@7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-explode-assignable-expression@7.18.6: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} @@ -213,14 +237,12 @@ packages: dependencies: '@babel/template': 7.20.7 '@babel/types': 7.20.7 - dev: true /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.7 - dev: true /@babel/helper-member-expression-to-functions@7.20.7: resolution: {integrity: sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==} @@ -249,7 +271,6 @@ packages: '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color - dev: true /@babel/helper-optimise-call-expression@7.18.6: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} @@ -297,7 +318,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.7 - dev: true /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} @@ -311,7 +331,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.7 - dev: true /@babel/helper-string-parser@7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} @@ -324,7 +343,6 @@ packages: /@babel/helper-validator-option@7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-wrap-function@7.20.5: resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} @@ -347,7 +365,6 @@ packages: '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color - dev: true /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} @@ -357,13 +374,12 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.20.15: - resolution: {integrity: sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==} + /@babel/parser@7.22.5: + resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} engines: {node: '>=6.0.0'} hasBin: true dependencies: '@babel/types': 7.20.7 - dev: true /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.20.12): resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} @@ -1150,6 +1166,14 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true + /@babel/polyfill@7.12.1: + resolution: {integrity: sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==} + deprecated: 🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information. + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.13.11 + dev: false + /@babel/preset-env@7.20.2(@babel/core@7.20.12): resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} engines: {node: '>=6.9.0'} @@ -1288,14 +1312,18 @@ packages: dependencies: regenerator-runtime: 0.13.11 + /@babel/standalone@7.22.5: + resolution: {integrity: sha512-6Lwhzral4YDEbIM3dBC8/w0BMDvOosGBGaJWSORLkerx8byawkmwwzXKUB0jGlI1Zp90+cK2uyTl62UPtLbUjQ==} + engines: {node: '>=6.9.0'} + dev: false + /@babel/template@7.20.7: resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.15 + '@babel/parser': 7.22.5 '@babel/types': 7.20.7 - dev: true /@babel/traverse@7.20.13: resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} @@ -1307,13 +1335,12 @@ packages: '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.15 + '@babel/parser': 7.22.5 '@babel/types': 7.20.7 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true /@babel/types@7.20.7: resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} @@ -2996,7 +3023,6 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/gen-mapping@0.3.2: resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} @@ -3005,28 +3031,23 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 '@jridgewell/trace-mapping': 0.3.17 - dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true /@jridgewell/trace-mapping@0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -3106,7 +3127,7 @@ packages: dependencies: '@babel/core': 7.20.12 '@babel/generator': 7.20.14 - '@babel/parser': 7.20.15 + '@babel/parser': 7.22.5 '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.20.12) '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.20.12) '@babel/preset-env': 7.20.2(@babel/core@7.20.12) @@ -4059,7 +4080,6 @@ packages: electron-to-chromium: 1.4.296 node-releases: 2.0.10 update-browserslist-db: 1.0.10(browserslist@4.21.5) - dev: true /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -4140,7 +4160,6 @@ packages: /caniuse-lite@1.0.30001452: resolution: {integrity: sha512-Lkp0vFjMkBB3GTpLR8zk4NwW5EdRdnitwYJHDOOKIU85x4ckYCPQ+9WlVvSVClHxVReefkUMtWZH2l9KGlD51w==} - dev: true /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -4330,6 +4349,17 @@ packages: browserslist: 4.21.5 dev: true + /core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + requiresBuild: true + dev: false + + /core-js@3.31.0: + resolution: {integrity: sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ==} + requiresBuild: true + dev: false + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true @@ -4423,7 +4453,6 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true /decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -4468,6 +4497,11 @@ packages: resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} dev: true + /deepmerge@3.3.0: + resolution: {integrity: sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==} + engines: {node: '>=0.10.0'} + dev: false + /deepmerge@4.3.0: resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==} engines: {node: '>=0.10.0'} @@ -4583,7 +4617,6 @@ packages: /electron-to-chromium@1.4.296: resolution: {integrity: sha512-i/6Q+Y9bluDa2a0NbMvdtG5TuS/1Fr3TKK8L+7UUL9QjRS5iFJzCC3r70xjyOnLiYG8qGV4/mMpe6HuAbdJW4w==} - dev: true /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4762,7 +4795,6 @@ packages: /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - dev: true /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -5535,7 +5567,6 @@ packages: /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - dev: true /get-intrinsic@1.2.0: resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} @@ -5628,7 +5659,6 @@ packages: /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - dev: true /globals@13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} @@ -6085,6 +6115,10 @@ packages: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} dev: true + /is-mergeable-object@1.1.1: + resolution: {integrity: sha512-CPduJfuGg8h8vW74WOxHtHmtQutyQBzR+3MjQ6iDHIYdbOnm1YC7jv43SqCoU8OPGTJD4nibmiryA4kmogbGrA==} + dev: false + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -6257,7 +6291,6 @@ packages: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true - dev: true /jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} @@ -6291,7 +6324,6 @@ packages: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - dev: true /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} @@ -6386,6 +6418,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true @@ -6433,7 +6469,6 @@ packages: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: yallist: 3.1.1 - dev: true /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} @@ -7016,7 +7051,6 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -7067,7 +7101,6 @@ packages: /node-releases@2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} - dev: true /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -7377,7 +7410,6 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -7510,7 +7542,6 @@ packages: resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} engines: {node: '>=10.13.0'} hasBin: true - dev: true /pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} @@ -8046,7 +8077,6 @@ packages: /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true - dev: true /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} @@ -8131,6 +8161,25 @@ packages: engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} dev: true + /smarts@2.0.3: + resolution: {integrity: sha512-42Xy0lJd2gP6g7pg2+ADa6VuSbF2S2QSTHm2H/Wj+4TiHE6Ekyz6LntJ6bloNPfYFEh6o5jnfjNurzfWlcQKiw==} + dependencies: + '@babel/core': 7.20.12 + '@babel/generator': 7.20.14 + '@babel/parser': 7.22.5 + '@babel/polyfill': 7.12.1 + '@babel/standalone': 7.22.5 + '@babel/template': 7.20.7 + '@babel/types': 7.20.7 + core-js: 3.31.0 + deepmerge: 3.3.0 + is-mergeable-object: 1.1.1 + prettier: 2.7.1 + uuid: 3.4.0 + transitivePeerDependencies: + - supports-color + dev: false + /socks-proxy-agent@5.0.1: resolution: {integrity: sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==} engines: {node: '>= 6'} @@ -8668,7 +8717,6 @@ packages: browserslist: 4.21.5 escalade: 3.1.1 picocolors: 1.0.0 - dev: true /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -8732,6 +8780,17 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + /uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: false + + /uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: false + /uvu@0.5.6: resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} engines: {node: '>=8'} @@ -8973,7 +9032,6 @@ packages: /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} diff --git a/remix/tsconfig.json b/remix/tsconfig.json index 20f8a38..7794110 100644 --- a/remix/tsconfig.json +++ b/remix/tsconfig.json @@ -1,6 +1,7 @@ { "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], "compilerOptions": { + "noImplicitAny": false, "lib": ["DOM", "DOM.Iterable", "ES2019"], "isolatedModules": true, "esModuleInterop": true,