jotai
Version:
👻 Next gen state management that will spook you
123 lines (119 loc) • 3.89 kB
JavaScript
System.register(['xstate', 'jotai'], (function (exports) {
'use strict';
var interpret, atom;
return {
setters: [function (module) {
interpret = module.interpret;
}, function (module) {
atom = module.atom;
}],
execute: (function () {
exports('atomWithMachine', atomWithMachine);
const RESTART = exports('RESTART', Symbol());
function atomWithMachine(getMachine, getOptions) {
const cachedMachineAtom = atom(null);
const machineAtom = atom(
(get) => {
const cachedMachine = get(cachedMachineAtom);
if (cachedMachine) {
return cachedMachine;
}
let initializing = true;
const safeGet = (a) => {
if (initializing) {
return get(a);
}
throw new Error("get not allowed after initialization");
};
const machine = isGetter(getMachine) ? getMachine(safeGet) : getMachine;
const options = isGetter(getOptions) ? getOptions(safeGet) : getOptions;
initializing = false;
const {
guards,
actions,
services,
delays,
context,
...interpreterOptions
} = options || {};
const machineConfig = {
...guards && { guards },
...actions && { actions },
...services && { services },
...delays && { delays }
};
const machineWithConfig = machine.withConfig(
machineConfig,
() => ({
...machine.context,
...context
})
);
const service = interpret(machineWithConfig, interpreterOptions);
return { machine: machineWithConfig, service };
},
(get, set, _arg) => {
set(cachedMachineAtom, get(machineAtom));
}
);
machineAtom.onMount = (commit) => {
commit();
};
const cachedMachineStateAtom = atom(null);
const machineStateAtom = atom(
(get) => {
var _a;
return (_a = get(cachedMachineStateAtom)) != null ? _a : get(machineAtom).machine.initialState;
},
(get, set, registerCleanup) => {
const { service } = get(machineAtom);
service.onTransition((nextState) => {
set(cachedMachineStateAtom, nextState);
});
service.start();
registerCleanup(() => {
const { service: service2 } = get(machineAtom);
service2.stop();
});
}
);
machineStateAtom.onMount = (initialize) => {
let unsub;
initialize((cleanup) => {
if (unsub === false) {
cleanup();
} else {
unsub = cleanup;
}
});
return () => {
if (unsub) {
unsub();
}
unsub = false;
};
};
const machineStateWithServiceAtom = atom(
(get) => get(machineStateAtom),
(get, set, event) => {
const { service } = get(machineAtom);
if (event === RESTART) {
service.stop();
set(cachedMachineAtom, null);
set(machineAtom, null);
const { service: newService } = get(machineAtom);
newService.onTransition((nextState) => {
set(cachedMachineStateAtom, nextState);
});
newService.start();
} else {
service.send(event);
}
}
);
return machineStateWithServiceAtom;
}
const isGetter = (v) => typeof v === "function";
})
};
}));