UNPKG

4.51 kBJavaScriptView Raw
1System.register(['@babel/template'], (function (exports) {
2 'use strict';
3 var _templateBuilder;
4 return {
5 setters: [function (module) {
6 _templateBuilder = module.default;
7 }],
8 execute: (function () {
9
10 exports('default', reactRefreshPlugin);
11
12 function isAtom(t, callee, customAtomNames = []) {
13 const atomNames = [...atomFunctionNames, ...customAtomNames];
14 if (t.isIdentifier(callee) && atomNames.includes(callee.name)) {
15 return true;
16 }
17 if (t.isMemberExpression(callee)) {
18 const { property } = callee;
19 if (t.isIdentifier(property) && atomNames.includes(property.name)) {
20 return true;
21 }
22 }
23 return false;
24 }
25 const atomFunctionNames = [
26 // Core
27 "atom",
28 "atomFamily",
29 "atomWithDefault",
30 "atomWithObservable",
31 "atomWithReducer",
32 "atomWithReset",
33 "atomWithStorage",
34 "freezeAtom",
35 "loadable",
36 "selectAtom",
37 "splitAtom",
38 "unstable_unwrap",
39 // jotai-xstate
40 "atomWithMachine",
41 // jotai-immer
42 "atomWithImmer",
43 // jotai-valtio
44 "atomWithProxy",
45 // jotai-trpc + jotai-relay
46 "atomWithQuery",
47 "atomWithMutation",
48 "atomWithSubscription",
49 // jotai-redux + jotai-zustand
50 "atomWithStore",
51 // jotai-location
52 "atomWithHash",
53 "atomWithLocation",
54 // jotai-optics
55 "focusAtom",
56 // jotai-form
57 "atomWithValidate",
58 "validateAtoms",
59 // jotai-cache
60 "atomWithCache",
61 // jotai-recoil
62 "atomWithRecoilValue"
63 ];
64
65 const templateBuilder = _templateBuilder.default || _templateBuilder;
66 function reactRefreshPlugin({ types: t }, options) {
67 return {
68 pre({ opts }) {
69 if (!opts.filename) {
70 throw new Error("Filename must be available");
71 }
72 },
73 visitor: {
74 Program: {
75 exit(path) {
76 const jotaiAtomCache = templateBuilder(`
77 globalThis.jotaiAtomCache = globalThis.jotaiAtomCache || {
78 cache: new Map(),
79 get(name, inst) {
80 if (this.cache.has(name)) {
81 return this.cache.get(name)
82 }
83 this.cache.set(name, inst)
84 return inst
85 },
86 }`)();
87 path.unshiftContainer("body", jotaiAtomCache);
88 }
89 },
90 ExportDefaultDeclaration(nodePath, state) {
91 const { node } = nodePath;
92 if (t.isCallExpression(node.declaration) && isAtom(t, node.declaration.callee, options == null ? void 0 : options.customAtomNames)) {
93 const filename = state.filename || "unknown";
94 const atomKey = `${filename}/defaultExport`;
95 const buildExport = templateBuilder(
96 `export default globalThis.jotaiAtomCache.get(%%atomKey%%, %%atom%%)`
97 );
98 const ast = buildExport({
99 atomKey: t.stringLiteral(atomKey),
100 atom: node.declaration
101 });
102 nodePath.replaceWith(ast);
103 }
104 },
105 VariableDeclarator(nodePath, state) {
106 var _a, _b;
107 if (t.isIdentifier(nodePath.node.id) && t.isCallExpression(nodePath.node.init) && isAtom(t, nodePath.node.init.callee, options == null ? void 0 : options.customAtomNames) && // Make sure atom declaration is in module scope
108 (((_a = nodePath.parentPath.parentPath) == null ? void 0 : _a.isProgram()) || ((_b = nodePath.parentPath.parentPath) == null ? void 0 : _b.isExportNamedDeclaration()))) {
109 const filename = state.filename || "unknown";
110 const atomKey = `${filename}/${nodePath.node.id.name}`;
111 const buildAtomDeclaration = templateBuilder(
112 `const %%atomIdentifier%% = globalThis.jotaiAtomCache.get(%%atomKey%%, %%atom%%)`
113 );
114 const ast = buildAtomDeclaration({
115 atomIdentifier: t.identifier(nodePath.node.id.name),
116 atomKey: t.stringLiteral(atomKey),
117 atom: nodePath.node.init
118 });
119 nodePath.parentPath.replaceWith(ast);
120 }
121 }
122 }
123 };
124 }
125
126 })
127 };
128}));