{"version":3,"file":"main.modern.mjs","sources":["../src/produce.ts","../src/Store.ts","../src/stand.ts"],"sourcesContent":["let tracking = true;\r\nlet triggering = true;\r\nlet packing = true;\r\nconst tracking_stack: boolean[] = [];\r\nconst triggering_stack: boolean[] = [];\r\nconst packing_stack: boolean[] = [];\r\nconst pauseTracking = () => {\r\n  tracking_stack.push(tracking);\r\n  tracking = false;\r\n};\r\nconst enableTracking = () => {\r\n  tracking_stack.push(tracking);\r\n  tracking = true;\r\n};\r\nconst resumeTracking = () => {\r\n  tracking = tracking_stack.pop() ?? true;\r\n  return tracking;\r\n};\r\nconst resetTracking = () => {\r\n  tracking = true;\r\n  tracking_stack.length = 0;\r\n};\r\nconst pauseTriggering = () => {\r\n  triggering_stack.push(triggering);\r\n  triggering = false;\r\n};\r\nconst enableTriggering = () => {\r\n  triggering_stack.push(triggering);\r\n  triggering = true;\r\n};\r\nconst resumeTriggering = () => {\r\n  triggering = triggering_stack.pop() ?? true;\r\n  return triggering;\r\n};\r\nconst resetTriggering = () => {\r\n  triggering = true;\r\n  triggering_stack.length = 0;\r\n};\r\nconst pausePacking = () => {\r\n  packing_stack.push(packing);\r\n  packing = false;\r\n};\r\nconst enablePacking = () => {\r\n  packing_stack.push(packing);\r\n  packing = true;\r\n};\r\nconst resumePacking = () => {\r\n  packing = packing_stack.pop() ?? true;\r\n  return packing;\r\n};\r\nconst resetPacking = () => {\r\n  packing = true;\r\n  packing_stack.length = 0;\r\n};\r\n\r\nexport const handlers = {\r\n  pauseTracking,\r\n  enableTracking,\r\n  resumeTracking,\r\n  resetTracking,\r\n\r\n  pauseTriggering,\r\n  enableTriggering,\r\n  resumeTriggering,\r\n  resetTriggering,\r\n\r\n  pausePacking,\r\n  enablePacking,\r\n  resumePacking,\r\n  resetPacking,\r\n};\r\n\r\nconst proxy2raw = new WeakMap<any, any>();\r\nexport const toRaw = <T>(x: T): T => {\r\n  while (proxy2raw.has(x)) {\r\n    x = proxy2raw.get(x)!;\r\n  }\r\n  return x;\r\n};\r\nexport const isProxy = (x: any): boolean => proxy2raw.has(x);\r\n\r\nexport type Patch = { path: string; value: any };\r\nexport function produce<State, Ret>(\r\n  baseObject: State,\r\n  operation: (x: State) => Ret,\r\n  patchCallback?: (patch: Patch) => any\r\n) {\r\n  const patches = [] as Patch[];\r\n  const deps = new Set<string>();\r\n  function createProxy(\r\n    target: any,\r\n    path = \"\",\r\n    topDeps: Set<string> = deps\r\n  ): any {\r\n    return new Proxy(target, {\r\n      get(target, property, receiver) {\r\n        const value = Reflect.get(target, property, receiver);\r\n        const dep = `${path}${path ? \".\" : \"\"}${String(property)}`;\r\n        if (tracking) topDeps.add(dep);\r\n        if (packing) {\r\n          if (value && typeof value === \"object\" && value !== null) {\r\n            const proxy = createProxy(value, dep, topDeps);\r\n            proxy2raw.set(proxy, value);\r\n            return proxy;\r\n          }\r\n        }\r\n        return value;\r\n      },\r\n      set(target, property, value) {\r\n        const ret = Reflect.set(target, property, value);\r\n        if (!triggering) {\r\n          return ret;\r\n        }\r\n        const fullPath = `${path}${path ? \".\" : \"\"}${String(property)}`;\r\n        const patch = { path: fullPath, value };\r\n        patches.push(patch);\r\n        patchCallback?.(patch);\r\n        return ret;\r\n      },\r\n    });\r\n  }\r\n  const proxy = createProxy(baseObject);\r\n  const result = operation(proxy);\r\n  return {\r\n    patches,\r\n    deps: Array.from(deps),\r\n    result,\r\n  };\r\n}\r\n","import { Patch, produce, handlers } from \"./produce\";\r\n\r\nexport type Listener<State> = (state: State, patches: Patch[]) => void;\r\nexport class Store<T> {\r\n  private state = {} as T;\r\n  private listeners = new Set<Listener<T>>();\r\n\r\n  setState(partial: Partial<T> | ((x: T) => Partial<T>)) {\r\n    const patches = [] as Patch[];\r\n    if (typeof partial === \"function\") {\r\n      try {\r\n        // NOTE: 因为这里不需要 deps 返回，所以也不需要收集依赖\r\n        handlers.pauseTracking();\r\n        handlers.pausePacking();\r\n        const { patches: newPatches, result } = produce(this.state, partial);\r\n        patches.push(...newPatches);\r\n        if (result && this.state !== result) {\r\n          this.state = {\r\n            ...this.state,\r\n            ...result,\r\n          };\r\n          patches.push(\r\n            ...Object.entries(result).map(([path, value]) => ({\r\n              path,\r\n              value,\r\n            }))\r\n          );\r\n        }\r\n      } finally {\r\n        handlers.resumeTracking();\r\n        handlers.resumePacking();\r\n      }\r\n    } else {\r\n      Object.entries(partial).forEach(([k, v]) =>\r\n        patches.push({\r\n          path: k,\r\n          value: v,\r\n        })\r\n      );\r\n      this.state = {\r\n        ...this.state,\r\n        ...partial,\r\n      };\r\n    }\r\n    this.listeners.forEach((listener) => listener(this.state, patches));\r\n  }\r\n\r\n  getState() {\r\n    return this.state;\r\n  }\r\n\r\n  subscribe(listener: Listener<T>) {\r\n    this.listeners.add(listener);\r\n    return () => this.listeners.delete(listener);\r\n  }\r\n\r\n  dispose() {\r\n    this.state = {} as T;\r\n    this.listeners.clear();\r\n  }\r\n}\r\n","import { produce } from \"./produce\";\r\nimport { Store } from \"./Store\";\r\nimport { SetupFn, Middleware, Selector, SelectorPath, UseStore } from \"./types\";\r\n\r\nconst isServer = typeof window === \"undefined\";\r\n\r\n/**\r\n * Binds a state and effect manager to a React component.\r\n *\r\n * @param {() => { createState: (x: any) => [() => any, (x: any) => any]; createEffect: (eff: () => () => any) => any; symbol: symbol; }} build - A function that builds the state and effect manager.\r\n * @return {function} A function that creates a state and effect manager.\r\n */\r\nexport function bind(\r\n  build: () => {\r\n    createState: (x: any) => [() => any, (x: any) => any];\r\n    createEffect: (eff: () => () => any) => any;\r\n    symbol: symbol;\r\n  }\r\n) {\r\n  /**\r\n   * Creates a store with the given setup and middlewares.\r\n   *\r\n   * @param {SetupFn<State>} setup - The function that sets up the initial state and effects.\r\n   * @param {Middleware<State>[]} middlewares - The array of middlewares to apply to the store.\r\n   * @return {UseStore<State>} The store object with the specified setup and middlewares.\r\n   */\r\n  function create<State>(\r\n    setup: SetupFn<State>,\r\n    ...middlewares: Middleware<State>[]\r\n  ) {\r\n    const store = new Store<State>();\r\n\r\n    // NOTE: ensure setter getter for middleware\r\n    const handlers = {\r\n      setter: store.setState.bind(store),\r\n      getter: store.getState.bind(store),\r\n      setter_ref: (x: any) => handlers.setter(x),\r\n      getter_ref: () => handlers.getter(),\r\n    };\r\n    // setup before middleware setup\r\n    store.setState(setup(handlers.setter_ref, handlers.getter_ref));\r\n\r\n    [handlers.setter, handlers.getter] = middlewares.reduce(\r\n      ([set, get], middleware) => middleware(set, get),\r\n      [handlers.setter, handlers.getter]\r\n    );\r\n\r\n    const envs = new WeakMap<\r\n      symbol,\r\n      {\r\n        deps: Set<string>;\r\n      }\r\n    >();\r\n\r\n    /**\r\n     * A function that manages state and effects based on the provided selector.\r\n     *\r\n     * @param {Selector<State, T> | SelectorPath<State>} selector - Optional selector for state management.\r\n     * @return {any} The updated state based on the selector.\r\n     */\r\n    function useStore<T>(selector?: Selector<State, T> | SelectorPath<State>) {\r\n      const select = (): any => {\r\n        const state = handlers.getter_ref();\r\n        return typeof selector === \"function\"\r\n          ? selector(state)\r\n          : selector\r\n          ? // TODO: support lodash.get like\r\n            state[selector]\r\n          : state;\r\n      };\r\n      const { createEffect, createState, symbol } = build();\r\n      const [getState, setState] = createState(select);\r\n\r\n      if (!envs.has(symbol)) envs.set(symbol, { deps: new Set() });\r\n      const { deps } = envs.get(symbol)!;\r\n\r\n      createEffect(() => {\r\n        // NOTE: never effects when run in server\r\n        if (isServer) return () => {};\r\n\r\n        const deps_arr =\r\n          typeof selector === \"function\"\r\n            ? produce(handlers.getter_ref(), selector).deps\r\n            : selector\r\n            ? [selector as any]\r\n            : [];\r\n        deps_arr.forEach((x) => deps.add(x));\r\n\r\n        const update = () => {\r\n          const selected = select();\r\n          setState(selected);\r\n        };\r\n\r\n        const unsubscribe = store.subscribe((state, patches) => {\r\n          const isChanged = patches.some(({ path }) =>\r\n            Array.from(deps).some((dep) => path.startsWith(dep as any))\r\n          );\r\n          if (!isChanged) return;\r\n          update();\r\n        });\r\n\r\n        update();\r\n        return () => {\r\n          unsubscribe();\r\n          // NOTE: Because it is a weakmap, I don't think it needs to be deleted, and the effect update should not affect the deps array.\r\n          // envs.delete(symbol);\r\n        };\r\n      });\r\n\r\n      const state = getState();\r\n      if (selector === undefined) {\r\n        return new Proxy(state, {\r\n          get(target, p, receiver) {\r\n            if (!isServer) {\r\n              deps.add(p as any);\r\n            }\r\n            return Reflect.get(target, p, receiver);\r\n          },\r\n        });\r\n      }\r\n      return state;\r\n    }\r\n\r\n    useStore.set = handlers.setter_ref;\r\n    useStore.get = handlers.getter_ref;\r\n    useStore.subscribe = store.subscribe.bind(store);\r\n    useStore._store = store;\r\n\r\n    return useStore as UseStore<State>;\r\n  }\r\n\r\n  return create;\r\n}\r\n\r\nconst NONE = Symbol();\r\n/**\r\n * Binds the given React library to create a state and effect manager.\r\n *\r\n * @param {any} react - The React library to bind.\r\n * @return {function} A function that creates a state and effect manager.\r\n */\r\nexport const bindReact = (react: any) =>\r\n  bind(() => {\r\n    const { useState, useEffect, useRef } = react;\r\n    const stateRef = useRef(NONE);\r\n    // NOTE: if based boolean, it may cause the rendering to be merged by fiber.\r\n    const markWorkInProgressReceivedUpdate = useState({})[1];\r\n    // NOTE: Symbols cannot be used as weak map keys in Node.js, so empty objects are used\r\n    const [symbol] = useState(() => ({}));\r\n    return {\r\n      createState: (state: any) => {\r\n        if (stateRef.current === NONE) {\r\n          if (typeof state === \"function\") {\r\n            stateRef.current = state();\r\n          } else {\r\n            stateRef.current = state;\r\n          }\r\n        }\r\n        return [\r\n          () => stateRef.current,\r\n          (x) => {\r\n            stateRef.current = x;\r\n            markWorkInProgressReceivedUpdate({});\r\n          },\r\n        ];\r\n      },\r\n      // eslint-disable-next-line react-hooks/exhaustive-deps, react-hooks/rules-of-hooks\r\n      createEffect: (x) => useEffect(x, []),\r\n      symbol,\r\n    };\r\n  });\r\n\r\nconst React = (globalThis as any).React;\r\n/**\r\n * Creates a store with the given setup and middlewares.\r\n *\r\n * @param {SetupFn<State>} setup - The function that sets up the initial state and effects.\r\n * @param {Middleware<State>[]} middlewares - The array of middlewares to apply to the store.\r\n * @return {UseStore<State>} The store object with the specified setup and middlewares.\r\n */\r\nexport const create = React\r\n  ? bindReact(React)\r\n  : () => {\r\n      throw new Error(\"no React\");\r\n    };\r\n\r\n// test code\r\n// const logger: Middleware<any> = (set, get) => {\r\n//   return [\r\n//     (x: any) => {\r\n//       set(x);\r\n//       console.log(`set: `, x);\r\n//     },\r\n//     () => {\r\n//       const state = get();\r\n//       console.log(`get: `, state);\r\n//       return state;\r\n//     },\r\n//   ];\r\n// };\r\n// const useStore = create<{\r\n//   count: number;\r\n//   inc: () => void;\r\n//   dec: () => void;\r\n// }>(\r\n//   (set, get) => ({\r\n//     count: 0,\r\n//     inc: () => set((state) => ({ count: state.count + 1 })),\r\n//     dec: () => set((state) => ({ count: state.count - 1 })),\r\n//   }),\r\n//   logger\r\n// );\r\n\r\n// const { count } = useStore();\r\n"],"names":["tracking","triggering","packing","tracking_stack","triggering_stack","packing_stack","handlers","pauseTracking","push","enableTracking","resumeTracking","_tracking_stack$pop","pop","resetTracking","length","pauseTriggering","enableTriggering","resumeTriggering","_triggering_stack$pop","resetTriggering","pausePacking","enablePacking","resumePacking","_packing_stack$pop","resetPacking","proxy2raw","WeakMap","toRaw","x","has","get","isProxy","produce","baseObject","operation","patchCallback","patches","deps","Set","result","createProxy","target","path","topDeps","Proxy","property","receiver","value","Reflect","dep","String","add","proxy","set","ret","patch","Array","from","Store","constructor","state","listeners","setState","partial","newPatches","this","_extends","Object","entries","map","forEach","k","v","listener","getState","subscribe","delete","dispose","clear","isServer","window","bind","build","setup","middlewares","store","setter","getter","setter_ref","getter_ref","reduce","middleware","envs","useStore","selector","select","createEffect","createState","symbol","update","selected","unsubscribe","some","startsWith","undefined","p","_store","NONE","Symbol","bindReact","react","useState","useEffect","useRef","stateRef","markWorkInProgressReceivedUpdate","current","React","globalThis","create","Error"],"mappings":"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"}