tungsten 0.4.14 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/.build-complete +1 -1
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/Components.d.ts +1 -0
  4. package/dist/Components.d.ts.map +1 -1
  5. package/dist/Components.js +2 -0
  6. package/dist/ContentNode.d.ts +8 -2
  7. package/dist/ContentNode.d.ts.map +1 -1
  8. package/dist/ContentNode.js +4 -1
  9. package/dist/Framework.js +4 -4
  10. package/dist/FrameworkConfig.d.ts +0 -2
  11. package/dist/FrameworkConfig.d.ts.map +1 -1
  12. package/dist/FunctionComponentStandIn.d.ts +1 -1
  13. package/dist/FunctionComponentStandIn.d.ts.map +1 -1
  14. package/dist/FunctionComponentStandIn.js +1 -0
  15. package/dist/Instance/Instance.js +2 -2
  16. package/dist/RenderingNode.d.ts +2 -2
  17. package/dist/RenderingNode.d.ts.map +1 -1
  18. package/dist/Script.d.ts +1 -1
  19. package/dist/Script.d.ts.map +1 -1
  20. package/dist/Servers/DevServer.d.ts.map +1 -1
  21. package/dist/Servers/DevServer.js +10 -0
  22. package/dist/Servers/loadEnvsDev.js +10 -10
  23. package/dist/Servers/routing.d.ts.map +1 -1
  24. package/dist/Servers/routing.js +8 -9
  25. package/dist/Store/makeStore.d.ts +4 -4
  26. package/dist/Store/makeStore.d.ts.map +1 -1
  27. package/dist/Store/makeStore.js +23 -57
  28. package/dist/babelPlugins/BabelTransformDocInit.d.ts +9 -0
  29. package/dist/babelPlugins/BabelTransformDocInit.d.ts.map +1 -0
  30. package/dist/babelPlugins/BabelTransformDocInit.js +201 -0
  31. package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
  32. package/dist/babelPlugins/BabelTransformPackageImports.js +1 -10
  33. package/dist/bin/index.d.ts.map +1 -1
  34. package/dist/bin/index.js +82 -75
  35. package/dist/browserStorage.d.ts +56 -18
  36. package/dist/browserStorage.d.ts.map +1 -1
  37. package/dist/browserStorage.js +172 -102
  38. package/dist/build/bundle.d.ts +1 -1
  39. package/dist/build/bundle.d.ts.map +1 -1
  40. package/dist/build/bundle.js +45 -40
  41. package/dist/build/compileJavascript.d.ts.map +1 -1
  42. package/dist/build/compileJavascript.js +0 -1
  43. package/dist/build/makeBabelUserDevConfig.d.ts.map +1 -1
  44. package/dist/build/makeBabelUserDevConfig.js +5 -1
  45. package/dist/build/makeBabelUserProdConfig.d.ts.map +1 -1
  46. package/dist/build/makeBabelUserProdConfig.js +5 -1
  47. package/dist/cliOutput.d.ts +5 -0
  48. package/dist/cliOutput.d.ts.map +1 -1
  49. package/dist/cliOutput.js +22 -0
  50. package/dist/components/Link.d.ts +1 -1
  51. package/dist/components/Link.d.ts.map +1 -1
  52. package/dist/components/NativeHtml.d.ts +10 -0
  53. package/dist/components/NativeHtml.d.ts.map +1 -0
  54. package/dist/components/NativeHtml.js +12 -0
  55. package/dist/components/PopMessages.d.ts +1 -1
  56. package/dist/components/PopMessages.d.ts.map +1 -1
  57. package/dist/components/Protected.d.ts +10 -0
  58. package/dist/components/Protected.d.ts.map +1 -0
  59. package/dist/components/Protected.js +12 -0
  60. package/dist/components/Stylesheet.d.ts +1 -1
  61. package/dist/components/Stylesheet.d.ts.map +1 -1
  62. package/dist/components/bindable/BindableCheckbox.d.ts +1 -1
  63. package/dist/components/bindable/BindableCheckbox.d.ts.map +1 -1
  64. package/dist/components/bindable/BindableInput.d.ts +1 -1
  65. package/dist/components/bindable/BindableInput.d.ts.map +1 -1
  66. package/dist/components/bindable/BindableInputNonString.d.ts +1 -1
  67. package/dist/components/bindable/BindableInputNonString.d.ts.map +1 -1
  68. package/dist/components/bindable/BindableInputString.d.ts +1 -1
  69. package/dist/components/bindable/BindableInputString.d.ts.map +1 -1
  70. package/dist/components/bindable/BindableInputTyped.d.ts +1 -1
  71. package/dist/components/bindable/BindableInputTyped.d.ts.map +1 -1
  72. package/dist/components/bindable/BindableInputTypedLegacy.d.ts +1 -1
  73. package/dist/components/bindable/BindableInputTypedLegacy.d.ts.map +1 -1
  74. package/dist/components/bindable/BindableRadio.d.ts +1 -1
  75. package/dist/components/bindable/BindableRadio.d.ts.map +1 -1
  76. package/dist/components/bindable/BindableSelect.d.ts +1 -1
  77. package/dist/components/bindable/BindableSelect.d.ts.map +1 -1
  78. package/dist/components/bindable/BindableTextarea.d.ts +1 -1
  79. package/dist/components/bindable/BindableTextarea.d.ts.map +1 -1
  80. package/dist/components/library/RichTextEditor/RichTextEditor.d.ts +1 -1
  81. package/dist/components/library/RichTextEditor/RichTextEditor.d.ts.map +1 -1
  82. package/dist/components/library/RichTextEditor/contentTree.d.ts.map +1 -1
  83. package/dist/components/library/RichTextEditor/contentTree.js +2 -1
  84. package/dist/components/library/__StatefulMessage/StatefulMessage.d.ts +1 -1
  85. package/dist/components/library/__StatefulMessage/StatefulMessage.d.ts.map +1 -1
  86. package/dist/defaultConfig.d.ts.map +1 -1
  87. package/dist/defaultConfig.js +0 -1
  88. package/dist/devBanner.d.ts +4 -0
  89. package/dist/devBanner.d.ts.map +1 -0
  90. package/dist/devBanner.js +50 -0
  91. package/dist/docInit.d.ts +16 -0
  92. package/dist/docInit.d.ts.map +1 -0
  93. package/dist/docInit.js +54 -0
  94. package/dist/env/getEnvSchemas.d.ts +1 -1
  95. package/dist/env/getEnvSchemas.d.ts.map +1 -1
  96. package/dist/env/getEnvSchemas.js +21 -22
  97. package/dist/env/registerEnvSchemas.d.ts +13 -0
  98. package/dist/env/registerEnvSchemas.d.ts.map +1 -0
  99. package/dist/env/registerEnvSchemas.js +23 -0
  100. package/dist/frameworkConfigSchema.d.ts +0 -2
  101. package/dist/frameworkConfigSchema.d.ts.map +1 -1
  102. package/dist/frameworkConfigSchema.js +0 -1
  103. package/dist/hydrate/hydrate.d.ts.map +1 -1
  104. package/dist/hydrate/hydrate.js +11 -2
  105. package/dist/hydrate/renderHydrationMismatchBanner.d.ts +1 -0
  106. package/dist/hydrate/renderHydrationMismatchBanner.d.ts.map +1 -1
  107. package/dist/hydrate/renderHydrationMismatchBanner.js +11 -63
  108. package/dist/indexInner.d.ts +5 -1
  109. package/dist/indexInner.d.ts.map +1 -1
  110. package/dist/indexInner.js +5 -1
  111. package/dist/jsxRuntime.d.ts +1 -1
  112. package/dist/jsxRuntime.d.ts.map +1 -1
  113. package/dist/jsxRuntime.js +9 -7
  114. package/dist/jsxRuntimeSignals.d.ts +8 -4
  115. package/dist/jsxRuntimeSignals.d.ts.map +1 -1
  116. package/dist/jsxRuntimeSignals.js +8 -6
  117. package/dist/nbsp.d.ts +2 -2
  118. package/dist/nbsp.d.ts.map +1 -1
  119. package/dist/rawHtml/filterContentNode.d.ts.map +1 -1
  120. package/dist/rawHtml/filterContentNode.js +3 -1
  121. package/dist/render/HeadData.d.ts +1 -0
  122. package/dist/render/HeadData.d.ts.map +1 -1
  123. package/dist/render/contentNodeToHtml.d.ts.map +1 -1
  124. package/dist/render/contentNodeToHtml.js +2 -1
  125. package/dist/render/contentToHtml.d.ts.map +1 -1
  126. package/dist/render/contentToHtml.js +3 -1
  127. package/dist/render/contentTreeToRenderingTree.d.ts.map +1 -1
  128. package/dist/render/contentTreeToRenderingTree.js +5 -1
  129. package/dist/render/processHead.d.ts.map +1 -1
  130. package/dist/render/processHead.js +10 -0
  131. package/dist/render/readDocInitScript.d.ts +3 -0
  132. package/dist/render/readDocInitScript.d.ts.map +1 -0
  133. package/dist/render/readDocInitScript.js +15 -0
  134. package/dist/render/rootToHtmlDev.d.ts.map +1 -1
  135. package/dist/routing/Group.d.ts +1 -1
  136. package/dist/routing/Group.d.ts.map +1 -1
  137. package/dist/routing/MatchedRoute.d.ts +1 -1
  138. package/dist/routing/MatchedRoute.d.ts.map +1 -1
  139. package/dist/settings.d.ts +3 -0
  140. package/dist/settings.d.ts.map +1 -1
  141. package/dist/settings.js +4 -0
  142. package/dist/style/styleContentSxy.d.ts.map +1 -1
  143. package/dist/style/styleContentSxy.js +6 -1
  144. package/dist/testing/installTestDocInit.d.ts +2 -0
  145. package/dist/testing/installTestDocInit.d.ts.map +1 -0
  146. package/dist/testing/installTestDocInit.js +6 -0
  147. package/dist/throwError.d.ts.map +1 -1
  148. package/dist/throwError.js +4 -1
  149. package/dist/update/integrateUpdateVdom.d.ts.map +1 -1
  150. package/dist/update/integrateUpdateVdom.js +39 -3
  151. package/package.json +2 -1
  152. package/readme.md +2 -135
  153. package/types/assets.d.ts +21 -0
  154. package/types/index.d.ts +24 -29
  155. package/types/jsx/html.d.ts +0 -1
  156. package/types/jsx/html.global.d.ts +0 -1
  157. package/types/jsx/html.values.d.ts +0 -1
  158. package/types/jsx/jsx.d.ts +8 -8
  159. package/vendor/manifest.json +2 -2
@@ -7,81 +7,47 @@ function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
7
7
  function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
8
8
  function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
9
9
  import { objectMap } from '../objectMap.js';
10
- import { isBrowser } from '../isBrowser.js';
11
- var _key = /*#__PURE__*/new WeakMap();
10
+ // the server render is one pass, so nothing re-renders on a write: no subscribers, and subscribe
11
+ // is a no-op that keeps the cell's shape for the component proxy
12
12
  var _value = /*#__PURE__*/new WeakMap();
13
- var _subscribedElements = /*#__PURE__*/new WeakMap();
14
- var _subscribers = /*#__PURE__*/new WeakMap();
15
13
  var _serverDataLoading = /*#__PURE__*/new WeakMap();
16
14
  export class StoreValueServer {
17
- constructor(key, value, subscribedElements, serverDataLoading) {
18
- _classPrivateFieldInitSpec(this, _key, void 0);
15
+ constructor(value, serverDataLoading) {
19
16
  _classPrivateFieldInitSpec(this, _value, void 0);
20
- _classPrivateFieldInitSpec(this, _subscribedElements, void 0);
21
- _classPrivateFieldInitSpec(this, _subscribers, new Set());
22
17
  _classPrivateFieldInitSpec(this, _serverDataLoading, void 0);
23
18
  _defineProperty(this, "get", () => _classPrivateFieldGet(_value, this));
24
19
  _defineProperty(this, "set", newValue => {
25
20
  _classPrivateFieldSet(_value, this, newValue);
26
- //console.log(this.#key, 'pushing', this.#subscribers)
27
- for (const element of _classPrivateFieldGet(_subscribers, this)) {
28
- if (element.shouldStoreComponentUpdate !== undefined) {
29
- if (!element.shouldStoreComponentUpdate(_classPrivateFieldGet(_key, this), _classPrivateFieldGet(_value, this))) {
30
- continue;
31
- }
32
- }
33
- //console.log('queueing update for', element.constructor.name, 'on', this.#key)
34
- element.__queueUpdate();
35
- }
36
21
  if (_classPrivateFieldGet(_serverDataLoading, this).value) {
37
- // save this for network export
22
+ // save this for network export
38
23
  // huh?
39
24
  }
40
25
  });
41
- _defineProperty(this, "subscribe", element => {
42
- if (isBrowser) console.log('StoreValueServer.subscribe', 'IS browser!');
43
- if (isBrowser) _classPrivateFieldGet(_subscribers, this).add(element);
44
- /* ???
45
- if (!this.#store.#subscriptions.exists(element) this.#store.#subscriptions.add(element)
46
- this.#store.#subscriptions.get(element).add(this)
47
- */
48
- });
49
- _defineProperty(this, "unsubscribe", element => {
50
- //console.log('StoreValueServer unsubscribe', this.#key, element)
51
- _classPrivateFieldGet(_subscribers, this).delete(element);
52
- //console.log('Subs', this.#subscribers)
53
- });
54
- _defineProperty(this, "sync", element => {
55
- if (isBrowser) console.log('StoreValueServer.sync', 'IS browser!');
56
- //if (isBrowser) this.#subscribers.add(element)
57
- //this.#subscribers.add(element)
58
- if (isBrowser) this.subscribe(element);
59
- return _classPrivateFieldGet(_value, this);
60
- });
61
- _classPrivateFieldSet(_key, this, key);
26
+ _defineProperty(this, "subscribe", () => {});
27
+ _defineProperty(this, "unsubscribe", () => {});
28
+ _defineProperty(this, "sync", () => _classPrivateFieldGet(_value, this));
62
29
  _classPrivateFieldSet(_value, this, value);
63
- _classPrivateFieldSet(_subscribedElements, this, subscribedElements);
64
30
  _classPrivateFieldSet(_serverDataLoading, this, serverDataLoading);
65
31
  }
66
32
  }
67
- var _key2 = /*#__PURE__*/new WeakMap();
33
+ var _key = /*#__PURE__*/new WeakMap();
68
34
  var _value2 = /*#__PURE__*/new WeakMap();
69
- var _subscribedElements2 = /*#__PURE__*/new WeakMap();
70
- var _subscribers2 = /*#__PURE__*/new WeakMap();
35
+ var _subscribedElements = /*#__PURE__*/new WeakMap();
36
+ var _subscribers = /*#__PURE__*/new WeakMap();
71
37
  export class StoreValue {
72
38
  constructor(key, value, subscribedElements) {
73
39
  /* #store: StoreSchemaClassGeneral */
74
- _classPrivateFieldInitSpec(this, _key2, void 0);
40
+ _classPrivateFieldInitSpec(this, _key, void 0);
75
41
  _classPrivateFieldInitSpec(this, _value2, void 0);
76
- _classPrivateFieldInitSpec(this, _subscribedElements2, void 0);
77
- _classPrivateFieldInitSpec(this, _subscribers2, new Set());
42
+ _classPrivateFieldInitSpec(this, _subscribedElements, void 0);
43
+ _classPrivateFieldInitSpec(this, _subscribers, new Set());
78
44
  _defineProperty(this, "get", () => _classPrivateFieldGet(_value2, this));
79
45
  _defineProperty(this, "set", newValue => {
80
46
  _classPrivateFieldSet(_value2, this, newValue);
81
47
  //console.log(this.#key, 'pushing', this.#subscribers)
82
- for (const element of _classPrivateFieldGet(_subscribers2, this)) {
48
+ for (const element of _classPrivateFieldGet(_subscribers, this)) {
83
49
  if (element.shouldStoreComponentUpdate !== undefined) {
84
- if (!element.shouldStoreComponentUpdate(_classPrivateFieldGet(_key2, this), _classPrivateFieldGet(_value2, this))) {
50
+ if (!element.shouldStoreComponentUpdate(_classPrivateFieldGet(_key, this), _classPrivateFieldGet(_value2, this))) {
85
51
  continue;
86
52
  }
87
53
  }
@@ -90,17 +56,17 @@ export class StoreValue {
90
56
  }
91
57
  });
92
58
  _defineProperty(this, "subscribe", element => {
93
- _classPrivateFieldGet(_subscribers2, this).add(element);
94
- let subscriptions = _classPrivateFieldGet(_subscribedElements2, this).get(element);
59
+ _classPrivateFieldGet(_subscribers, this).add(element);
60
+ let subscriptions = _classPrivateFieldGet(_subscribedElements, this).get(element);
95
61
  if (subscriptions === undefined) {
96
62
  subscriptions = new Set();
97
- _classPrivateFieldGet(_subscribedElements2, this).set(element, subscriptions);
63
+ _classPrivateFieldGet(_subscribedElements, this).set(element, subscriptions);
98
64
  }
99
- subscriptions.add(_classPrivateFieldGet(_key2, this));
65
+ subscriptions.add(_classPrivateFieldGet(_key, this));
100
66
  });
101
67
  _defineProperty(this, "unsubscribe", element => {
102
68
  //console.log('StoreValue unsubscribe', this.#key, element)
103
- _classPrivateFieldGet(_subscribers2, this).delete(element);
69
+ _classPrivateFieldGet(_subscribers, this).delete(element);
104
70
  //console.log('Subs', this.#subscribers)
105
71
  /*
106
72
  // it should always exist. But might be safer to check anyway
@@ -111,13 +77,13 @@ export class StoreValue {
111
77
  this.subscribe(element);
112
78
  return _classPrivateFieldGet(_value2, this);
113
79
  });
114
- _classPrivateFieldSet(_key2, this, key);
80
+ _classPrivateFieldSet(_key, this, key);
115
81
  _classPrivateFieldSet(_value2, this, value);
116
- _classPrivateFieldSet(_subscribedElements2, this, subscribedElements);
82
+ _classPrivateFieldSet(_subscribedElements, this, subscribedElements);
117
83
  }
118
84
  }
119
85
  export function makeStore(schema, subscribedElements, serverDataLoading = null) {
120
86
  //const Class = (isServer) ? StoreValueServer : StoreValue
121
- const store = objectMap(schema, (key, value) => serverDataLoading ? new StoreValueServer(key, value, subscribedElements, serverDataLoading) : new StoreValue(key, value, subscribedElements));
87
+ const store = objectMap(schema, (key, value) => serverDataLoading ? new StoreValueServer(value, serverDataLoading) : new StoreValue(key, value, subscribedElements));
122
88
  return store; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- not sure, just want to get rid of squigglies
123
89
  }
@@ -0,0 +1,9 @@
1
+ import type * as Babel from '@babel/core';
2
+ import type { PluginObj } from '@babel/core';
3
+ type Opts = {
4
+ outputFile: string;
5
+ projectDir?: string | undefined;
6
+ };
7
+ export declare function MakeBabelTransformDocInit(opts: Opts): (babel: typeof Babel) => PluginObj;
8
+ export {};
9
+ //# sourceMappingURL=BabelTransformDocInit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BabelTransformDocInit.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformDocInit.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAY,SAAS,EAAc,MAAM,aAAa,CAAA;AAQlE,KAAK,IAAI,GAAG;IACR,UAAU,EAAE,MAAM,CAAA;IAElB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAClC,CAAA;AAoCD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,IAqBV,OAAO,OAAO,KAAK,KAAG,SAAS,CAuKxE"}
@@ -0,0 +1,201 @@
1
+ // BabelTransformDocInit
2
+ //
3
+ // `DocInit(fn, serverValue)` - fn runs in the document head before <body>, so it has to be in the
4
+ // html, not the bundle. This rewrites each call to `docInit(<id>, serverValue)` (a read of the
5
+ // result, see src/docInit.ts) and collects fn into one generated script:
6
+ // window.__t_docInit = {};
7
+ // window.__t_docInitErrors = [];
8
+ // try { window.__t_docInit[<id>] = (fn)(); }
9
+ // catch (e) { window.__t_docInitErrors.push({ id: <id>, source: "<file>:<line>:<col> of fn", error: e }); throw e; }
10
+ // which the server inlines into the head (readDocInitScript.ts / processHead.ts). The catch only
11
+ // records: the throw stays uncaught in the head, so the console shows it where it happened and the
12
+ // script stops there as any other would. The record is for the dev banner hydrate renders
13
+ // (docInit.ts renderDocInitErrorBanner).
14
+ //
15
+ // DocInit is a global (types/index.d.ts), so a call is recognised by name: the callee must be the
16
+ // identifier with no binding in scope. Ids are one counter for the process, so a re-transform of a
17
+ // file under watch gives its calls fresh ids and the old ones go dead; the output file is rewritten
18
+ // whole from the per-file map each time, so dead entries never run. An untransformed call reaches
19
+ // the throwing global docInit.ts installs.
20
+ import fs from 'fs';
21
+ import { basename, dirname, relative, resolve } from 'path';
22
+ import { createRequire } from 'module';
23
+ import slash from '../slash.js';
24
+ import { docInitErrorsWindowKey, docInitWindowKey } from '../settings.js';
25
+ // The source-map reader, required on the first call that has a map: DocInit is rare, so most
26
+ // compiles never need it. The map itself babel has already read (inputSourceMap, on by default).
27
+ const require = createRequire(import.meta.url);
28
+ let traceMapping;
29
+ function loadTraceMapping() {
30
+ traceMapping ??= require('@jridgewell/trace-mapping'); // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- require() is untyped
31
+ return traceMapping;
32
+ }
33
+ const globalName = 'DocInit';
34
+ const runtimeName = 'docInit';
35
+ const runtimeModule = 'tungsten';
36
+ function isGlobalDocInitCall(path) {
37
+ const callee = path.node.callee;
38
+ return callee.type === 'Identifier' && callee.name === globalName && !path.scope.hasBinding(globalName);
39
+ }
40
+ function hasGlobalDocInitCall(program) {
41
+ let found = false;
42
+ program.traverse({
43
+ CallExpression(callPath) {
44
+ if (!isGlobalDocInitCall(callPath)) return;
45
+ found = true;
46
+ callPath.stop();
47
+ }
48
+ });
49
+ return found;
50
+ }
51
+ // Has side effects: empties the output file, so a stale one from an earlier run is never served
52
+ export function MakeBabelTransformDocInit(opts) {
53
+ const entriesByFile = new Map();
54
+ let nextId = 0;
55
+ fs.mkdirSync(dirname(opts.outputFile), {
56
+ recursive: true
57
+ });
58
+ fs.writeFileSync(opts.outputFile, '');
59
+ function writeOutputFile() {
60
+ const entries = [...entriesByFile.values()].flat().sort((a, b) => a.id - b.id);
61
+ fs.writeFileSync(opts.outputFile, entries.length === 0 ? '' : [`window.${docInitWindowKey} = {};`, `window.${docInitErrorsWindowKey} = [];`, ...entries.map(entry => entry.statement)].join('\n') + '\n');
62
+ }
63
+ return function BabelTransformDocInit(babel) {
64
+ const t = babel.types;
65
+ // per file; transforms are sync and sequential
66
+ let calls = [];
67
+ let runtimeLocal = null;
68
+ let tracer; // undefined: not looked for yet; null: the file has no map
69
+ // the fn can only run against the head's globals: anything it reaches from this module is gone
70
+ function checkSelfContained(fnPath) {
71
+ fnPath.traverse({
72
+ ReferencedIdentifier(idPath) {
73
+ if (!idPath.isIdentifier()) return;
74
+ const name = idPath.node.name;
75
+ const binding = idPath.scope.getBinding(name);
76
+ if (binding === undefined) return; // a real global: document, localStorage, ...
77
+ if (binding.path === fnPath || binding.path.isDescendant(fnPath)) return;
78
+ throw idPath.buildCodeFrameError(`${globalName}() function references '${name}' from outside the function. It runs in the` + ` document head, where nothing from this module exists - only globals like document and` + ` localStorage are available`);
79
+ },
80
+ ThisExpression(thisPath) {
81
+ const owner = thisPath.findParent(p => p.isFunction() && !p.isArrowFunctionExpression());
82
+ if (owner !== null && (owner === fnPath || owner.isDescendant(fnPath))) return;
83
+ throw thisPath.buildCodeFrameError(`'this' in a ${globalName}() function refers to the enclosing scope, which does not exist in` + ` the document head`);
84
+ }
85
+ });
86
+ }
87
+ function headStatement(id, fnNode, source) {
88
+ const windowKey = key => t.memberExpression(t.identifier('window'), t.identifier(key));
89
+ const assign = t.expressionStatement(t.assignmentExpression('=', t.memberExpression(windowKey(docInitWindowKey), t.numericLiteral(id), true), t.callExpression(t.cloneNode(fnNode, true), [])));
90
+ const record = t.expressionStatement(t.callExpression(t.memberExpression(windowKey(docInitErrorsWindowKey), t.identifier('push')), [t.objectExpression([t.objectProperty(t.identifier('id'), t.numericLiteral(id)), t.objectProperty(t.identifier('source'), t.stringLiteral(source)), t.objectProperty(t.identifier('error'), t.identifier('e'))])]));
91
+ const statement = t.tryStatement(t.blockStatement([assign]), t.catchClause(t.identifier('e'), t.blockStatement([record, t.throwStatement(t.identifier('e'))])));
92
+ const result = babel.transformFromAstSync(t.file(t.program([statement])), undefined, {
93
+ babelrc: false,
94
+ configFile: false,
95
+ ast: false,
96
+ code: true,
97
+ comments: false
98
+ });
99
+ if (result === null || typeof result.code !== 'string') {
100
+ throw new Error(`BabelTransformDocInit: could not generate the head entry for doc init ${id}`);
101
+ }
102
+ return result.code;
103
+ }
104
+ // where the file's source map says a position came from - the .tsx behind tsc's .jsx
105
+ function originalPosition(state, filename, line, column) {
106
+ const inputMap = state.file.inputMap;
107
+ if (inputMap === null) return undefined;
108
+ if (tracer === undefined) {
109
+ // babel hands over a convert-source-map object; the raw map is what the reader takes
110
+ const raw = 'toObject' in inputMap && typeof inputMap.toObject === 'function' ? inputMap.toObject() // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- untyped by babel
111
+ : inputMap;
112
+ tracer = new (loadTraceMapping().TraceMap)(raw); // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- as above
113
+ }
114
+ if (tracer === null) return undefined;
115
+ const position = loadTraceMapping().originalPositionFor(tracer, {
116
+ line,
117
+ column
118
+ });
119
+ if (position.source === null) return undefined;
120
+ // sources are relative to the map, which tsc writes beside the file
121
+ return {
122
+ file: resolve(dirname(filename), position.source),
123
+ line: position.line,
124
+ column: position.column
125
+ };
126
+ }
127
+ // file:line:column of the function itself, 1-based like an editor; the original source where a map says
128
+ function callSite(fnPath, state, filename) {
129
+ const displayPath = file => opts.projectDir === undefined ? basename(file) : slash(relative(opts.projectDir, file));
130
+ const start = fnPath.node.loc?.start;
131
+ if (start === undefined) return displayPath(filename);
132
+ const original = originalPosition(state, filename, start.line, start.column);
133
+ const {
134
+ file,
135
+ line,
136
+ column
137
+ } = original ?? {
138
+ file: filename,
139
+ line: start.line,
140
+ column: start.column
141
+ };
142
+ return `${displayPath(file)}:${line}:${column + 1}`;
143
+ }
144
+ function rewriteCall(callPath, local, state, filename) {
145
+ const args = callPath.get('arguments');
146
+ const fnPath = args[0];
147
+ if (fnPath === undefined || !(fnPath.isArrowFunctionExpression() || fnPath.isFunctionExpression())) {
148
+ throw callPath.buildCodeFrameError(`${globalName}() takes an inline function expression as its first argument - it is inlined` + ` into the document head at build, so it cannot be a reference`);
149
+ }
150
+ if (fnPath.node.async === true || fnPath.node.generator === true) {
151
+ throw fnPath.buildCodeFrameError(`a ${globalName}() function runs synchronously in the document head, so it cannot be async` + ` or a generator`);
152
+ }
153
+ if (fnPath.node.params.length > 0) {
154
+ throw fnPath.buildCodeFrameError(`a ${globalName}() function takes no parameters - nothing calls it with any`);
155
+ }
156
+ if (args.length > 2) {
157
+ throw callPath.buildCodeFrameError(`${globalName}() takes a function and an optional server value, nothing more`);
158
+ }
159
+ checkSelfContained(fnPath);
160
+ const id = nextId++;
161
+ const entry = {
162
+ id,
163
+ statement: headStatement(id, fnPath.node, callSite(fnPath, state, filename))
164
+ };
165
+ callPath.node.callee = t.identifier(local.name);
166
+ callPath.node.arguments = [t.numericLiteral(id), ...callPath.node.arguments.slice(1)];
167
+ return entry;
168
+ }
169
+ return {
170
+ name: 'BabelTransformDocInit',
171
+ visitor: {
172
+ Program: {
173
+ enter(path, state) {
174
+ calls = [];
175
+ runtimeLocal = null;
176
+ tracer = undefined;
177
+ // the substring gate keeps the pre-scan off the files that cannot need it
178
+ if (!state.file.code.includes(globalName)) return;
179
+ if (!hasGlobalDocInitCall(path)) return;
180
+ // inserted now, not at exit, so the other plugins see it as any other import
181
+ runtimeLocal = path.scope.generateUidIdentifier(runtimeName);
182
+ path.unshiftContainer('body', t.importDeclaration([t.importSpecifier(runtimeLocal, t.identifier(runtimeName))], t.stringLiteral(runtimeModule)));
183
+ },
184
+ // after the presets have run on the function bodies: types stripped, jsx compiled
185
+ exit(_path, state) {
186
+ const filename = state.filename ?? ''; // eslint-disable-line @typescript-eslint/no-unnecessary-condition -- tsc sees string | undefined here, eslint's type info does not
187
+ if (calls.length === 0 && !entriesByFile.has(filename)) return;
188
+ const local = runtimeLocal;
189
+ const entries = local === null ? [] : calls.map(callPath => rewriteCall(callPath, local, state, filename));
190
+ if (entries.length === 0) entriesByFile.delete(filename);else entriesByFile.set(filename, entries);
191
+ writeOutputFile();
192
+ }
193
+ },
194
+ CallExpression(path) {
195
+ if (runtimeLocal === null) return;
196
+ if (isGlobalDocInitCall(path)) calls.push(path);
197
+ }
198
+ }
199
+ };
200
+ };
201
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"BabelTransformPackageImports.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformPackageImports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BabelTransformPackageImports.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformPackageImports.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAMrD,OAAO,EAGH,QAAQ,EACX,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAsC5C,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;AAErE,MAAM,MAAM,QAAQ,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,EAAE,WAAW,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;AAEnD,MAAM,MAAM,WAAW,GAAG;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,WAAW,CAAA;IACjB,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACxB,CAAA;AAGD,MAAM,MAAM,WAAW,GAAG;IACtB,CAAC,GAAG,EAAC,MAAM,GAAG,WAAW,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACvC,KAAK,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,CAAC,GAAG,EAAC,MAAM,GAAG,cAAc,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,QAAQ,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,iCAAiC,GAAG,mBAAmB,GAAG;IAClE,cAAc,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,EAAE,CAAA;AAEnC,KAAK,IAAI,GAAG;IACR,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAChD,kBAAkB,EAAE,eAAe,CAAA;IACnC,eAAe,EAAE,eAAe,CAAA;IAChC,aAAa,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAGxC,QAAQ,EAAE,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAA;CAC/C,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;AAC3D,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,CAAA;AACjE,MAAM,MAAM,oCAAoC,GAC1C,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAA;AACpG,MAAM,MAAM,kCAAkC,GACxC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAmC,MAAM,CAAA;AAChF,MAAM,MAAM,uCAAuC,GAC7C,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAmC,MAAM,CAAA;AAChF,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,KAAK,MAAM,CAAA;AACrF,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAA;AAuDzF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,IAAI;;eAi8BpC,SAAS;;kCAkBmB,QAAQ,CAAC,iBAAiB,CAAC;;;EAmH7E"}
@@ -856,16 +856,7 @@ export function MakeBabelTransformPackageImports(opts) {
856
856
  const importTarget = tallied('resolve import target', () => resolveImportTarget(location, dirname(filename), require));
857
857
  // Should do some checking here to show helpful errors about bad imports
858
858
  if (importTarget === location) {
859
- //console.log()
860
- // errorOut(errorMessage(
861
- // 'BabelTransformPackageImports',
862
- // `import '${location}' in '${filename}' appears to refer to a node package.`
863
- // + ` This file is being processed as client-side code.`
864
- // + ` Client-side code cannot import node packages.`
865
- // + `\nIf you need to exclude files from client side compilation,`
866
- // + ` use exclude: glob-pattern in the project's ${packageName} config.`
867
- // ))
868
- throwError('BabelTransformPackageImports', `import '${location}' in '${filename}' appears to refer to a node package.` + ` This file is being processed as client-side code.` + ` Client-side code cannot import node packages.` + `\nIf you need to exclude files from client side compilation,` + ` use exclude: glob-pattern in the project's ${packageName} config.`);
859
+ throwError('BabelTransformPackageImports', `import '${location}' in '${filename}' appears to refer to a node package.` + ` This file is being processed as client-side code.` + ` Client-side code cannot import node packages.` + `\nTo keep a file out of client side compilation, use ignorePatterns` + ` (or clientDirs / rawDirs) in the project's ${packageName} config.`);
869
860
  return;
870
861
  }
871
862
  //console.log('** importTarget', importTarget)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"AAoHA,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"AA2HA,OAAO,EAAE,CAAA"}
package/dist/bin/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { enableCompileCache, flushCompileCache } from 'node:module';
2
- import { cliOut, cliWarn } from '../cliOutput.js';
2
+ import { cliFatal, cliOut, cliWarn } from '../cliOutput.js';
3
3
  import { beginStartupProfiling } from '../timeProfiler.js';
4
4
  // get command line args
5
5
  const args = process.argv.slice(2);
@@ -32,82 +32,89 @@ if (profileModulesArg !== undefined) {
32
32
  } = await import('./moduleLoadAnalysis.js');
33
33
  registerModuleLoadAnalysis(profileModulesArg.split('=')[1]);
34
34
  }
35
- switch (command) {
36
- case undefined:
37
- case '':
38
- case 'help':
39
- case '--help':
40
- case '-h':
41
- {
42
- await import('./commands/help.js');
43
- break;
44
- }
45
- case 'dev':
46
- {
47
- cliOut(`Starting Tungsten dev mode`);
48
- beginStartupProfiling(profile);
49
- // set env before loading the next file, to set the env before file imports
50
- process.env.__TUNGSTEN_ENV = 'development';
51
- await import('./commands/dev.js');
52
- break;
53
- }
54
- case 'devmon':
55
- {
56
- cliOut(`Starting Tungsten auto-restart dev mode`);
57
- process.env.__TUNGSTEN_ENV = 'development';
58
- await import('./commands/devmon.js');
59
- break;
60
- }
61
- case 'build':
62
- {
63
- if (args.includes('--help') || args.includes('-h')) {
64
- await import('./commands/buildHelp.js');
35
+ // a command module's top-level await rejecting is the command failing to start (an env schema
36
+ // that fails, a missing file): report it as such, not as node's uncaught-exception dump
37
+ try {
38
+ switch (command) {
39
+ case undefined:
40
+ case '':
41
+ case 'help':
42
+ case '--help':
43
+ case '-h':
44
+ {
45
+ await import('./commands/help.js');
65
46
  break;
66
47
  }
67
- // announce before the import: resolving the build's dependencies is a long silent wait
68
- if (!args.includes('--quiet')) cliOut(`Starting Tungsten production build`);
69
- beginStartupProfiling(profile);
70
- process.env.__TUNGSTEN_ENV = 'production';
71
- process.env.__TUNGSTEN_DEBUG = 'true';
72
- await import('./commands/build.js');
73
- break;
74
- }
75
- case 'start':
76
- {
77
- cliOut(`Starting Tungsten server`);
78
- process.env.__TUNGSTEN_ENV = 'production';
79
- await import('./commands/start.js');
80
- break;
81
- }
82
- case 'static':
83
- {
84
- cliOut(`Starting Tungsten static site preview`);
85
- //process.env.__TUNGSTEN_ENV = 'production'
86
- await import('./commands/static.js');
87
- break;
88
- }
89
- case 'clean':
90
- {
91
- await import('./commands/clean.js');
92
- break;
93
- }
94
- case 'compile':
95
- {
96
- beginStartupProfiling(profile);
97
- process.env.__TUNGSTEN_ENV = 'development';
98
- await import('./commands/compile.js');
99
- break;
100
- }
101
- case 'compile-simple-package':
102
- {
103
- await import('./commands/compileSimplePackage.js');
104
- break;
105
- }
106
- default:
107
- {
108
- cliWarn(`tungsten: unknown command "${command}" (run "tungsten --help" for usage)`);
109
- process.exit(1);
110
- }
48
+ case 'dev':
49
+ {
50
+ cliOut(`Starting Tungsten dev mode`);
51
+ beginStartupProfiling(profile);
52
+ // set env before loading the next file, to set the env before file imports
53
+ process.env.__TUNGSTEN_ENV = 'development';
54
+ await import('./commands/dev.js');
55
+ break;
56
+ }
57
+ case 'devmon':
58
+ {
59
+ cliOut(`Starting Tungsten auto-restart dev mode`);
60
+ process.env.__TUNGSTEN_ENV = 'development';
61
+ await import('./commands/devmon.js');
62
+ break;
63
+ }
64
+ case 'build':
65
+ {
66
+ if (args.includes('--help') || args.includes('-h')) {
67
+ await import('./commands/buildHelp.js');
68
+ break;
69
+ }
70
+ // announce before the import: resolving the build's dependencies is a long silent wait
71
+ if (!args.includes('--quiet')) cliOut(`Starting Tungsten production build`);
72
+ beginStartupProfiling(profile);
73
+ process.env.__TUNGSTEN_ENV = 'production';
74
+ process.env.__TUNGSTEN_DEBUG = 'true';
75
+ await import('./commands/build.js');
76
+ break;
77
+ }
78
+ case 'start':
79
+ {
80
+ cliOut(`Starting Tungsten server`);
81
+ process.env.__TUNGSTEN_ENV = 'production';
82
+ await import('./commands/start.js');
83
+ break;
84
+ }
85
+ case 'static':
86
+ {
87
+ cliOut(`Starting Tungsten static site preview`);
88
+ //process.env.__TUNGSTEN_ENV = 'production'
89
+ await import('./commands/static.js');
90
+ break;
91
+ }
92
+ case 'clean':
93
+ {
94
+ await import('./commands/clean.js');
95
+ break;
96
+ }
97
+ case 'compile':
98
+ {
99
+ beginStartupProfiling(profile);
100
+ process.env.__TUNGSTEN_ENV = 'development';
101
+ await import('./commands/compile.js');
102
+ break;
103
+ }
104
+ case 'compile-simple-package':
105
+ {
106
+ await import('./commands/compileSimplePackage.js');
107
+ break;
108
+ }
109
+ default:
110
+ {
111
+ cliWarn(`tungsten: unknown command "${command}" (run "tungsten --help" for usage)`);
112
+ process.exit(1);
113
+ }
114
+ }
115
+ } catch (e) {
116
+ cliFatal(e);
117
+ process.exit(1);
111
118
  }
112
119
  // Node only writes the compile cache when the process exits, and dev/start are killed rather than
113
120
  // exited - signals skip exit handling - so they would populate the cache and then throw it away,
@@ -1,26 +1,64 @@
1
1
  import { AnyComponent } from './AnyComponent.js';
2
- export declare class TungstenLocalStorage<LocalStorage extends object> {
3
- #private;
4
- get: <K extends keyof LocalStorage & string>(key: K) => LocalStorage[K] | undefined;
5
- set: <K extends keyof LocalStorage & string>(key: K, value: LocalStorage[K]) => void;
6
- clear: () => void;
7
- key: (index: number) => string | null;
8
- get length(): number;
9
- delete: <K extends keyof LocalStorage & string>(key: K) => void;
10
- subscribe: <K extends keyof LocalStorage & string>(element: AnyComponent, key: K) => void;
11
- sync: <K extends keyof LocalStorage & string>(element: AnyComponent, key: K) => LocalStorage[K] | undefined;
2
+ type StorageKey<Schema> = keyof Schema & string;
3
+ export interface Transformer<Allowed> {
4
+ stringify: (value: Allowed) => string;
5
+ parse: (text: string) => unknown;
12
6
  }
13
- export declare function makeLocalStorage<LocalStorage extends object>(): TungstenLocalStorage<LocalStorage>;
14
- export declare class TungstenSessionStorage<SessionStorage extends object> {
7
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
8
+ [key: string]: JsonValue;
9
+ };
10
+ export declare const rawTransformer: Transformer<string>;
11
+ export declare const jsonTransformer: Transformer<JsonValue>;
12
+ type AllStrings<Schema> = {
13
+ [K in keyof Schema]: string;
14
+ };
15
+ type TransformerFor<Schema extends object> = Transformer<Schema[StorageKey<Schema>]>;
16
+ type TransformerOption<Schema extends object> = Schema[StorageKey<Schema>] extends string ? {
17
+ transformer?: TransformerFor<Schema>;
18
+ } : {
19
+ transformer: TransformerFor<Schema>;
20
+ };
21
+ export type BrowserStorageOptions<Schema extends object> = {
22
+ defaults?: Schema;
23
+ serverDefaults?: Schema;
24
+ } & TransformerOption<Schema>;
25
+ export declare class TungstenBrowserStorage<Schema extends object, Missing = undefined> {
15
26
  #private;
16
- get: <K extends keyof SessionStorage & string>(key: K) => SessionStorage[K] | undefined;
17
- set: <K extends keyof SessionStorage & string>(key: K, value: SessionStorage[K]) => void;
27
+ constructor({ storage, transformer, defaults, host }: {
28
+ storage: Storage;
29
+ transformer: TransformerFor<Schema>;
30
+ defaults?: Schema | undefined;
31
+ host?: Window | null;
32
+ });
33
+ [Symbol.dispose](): void;
34
+ get: <K extends StorageKey<Schema>>(key: K) => Schema[K] | Missing;
35
+ set: <K extends StorageKey<Schema>>(key: K, value: Schema[K]) => void;
18
36
  clear: () => void;
19
37
  key: (index: number) => string | null;
20
38
  get length(): number;
21
- delete: <K extends keyof SessionStorage & string>(key: K) => void;
22
- subscribe: <K extends keyof SessionStorage & string>(element: AnyComponent, key: K) => void;
23
- sync: <K extends keyof SessionStorage & string>(element: AnyComponent, key: K) => SessionStorage[K] | undefined;
39
+ delete: <K extends StorageKey<Schema>>(key: K) => void;
40
+ subscribe: <K extends StorageKey<Schema>>(element: AnyComponent, key: K) => void;
41
+ unsubscribe: <K extends StorageKey<Schema>>(element: AnyComponent, key: K) => void;
42
+ unsubscribeAll: (element: AnyComponent) => void;
43
+ sync: <K extends StorageKey<Schema>>(element: AnyComponent, key: K) => Missing | Schema[K];
44
+ }
45
+ export declare class TungstenLocalStorage<LocalStorage extends object, Missing = undefined> extends TungstenBrowserStorage<LocalStorage, Missing> {
46
+ constructor(transformer: TransformerFor<LocalStorage>, defaults?: LocalStorage | undefined);
47
+ }
48
+ export declare class TungstenSessionStorage<SessionStorage extends object, Missing = undefined> extends TungstenBrowserStorage<SessionStorage, Missing> {
49
+ constructor(transformer: TransformerFor<SessionStorage>, defaults?: SessionStorage | undefined);
24
50
  }
25
- export declare function makeSessionStorage<SessionStorage extends object>(): TungstenSessionStorage<SessionStorage>;
51
+ type WithDefaults<Schema extends object> = BrowserStorageOptions<Schema> & {
52
+ defaults: Schema;
53
+ };
54
+ type WithoutDefaults<Schema extends object> = BrowserStorageOptions<Schema> & {
55
+ defaults?: undefined;
56
+ };
57
+ export declare function makeLocalStorage<LocalStorage extends AllStrings<LocalStorage>>(): TungstenLocalStorage<LocalStorage>;
58
+ export declare function makeLocalStorage<LocalStorage extends object>(options: WithDefaults<LocalStorage>): TungstenLocalStorage<LocalStorage, never>;
59
+ export declare function makeLocalStorage<LocalStorage extends object>(options: WithoutDefaults<LocalStorage>): TungstenLocalStorage<LocalStorage>;
60
+ export declare function makeSessionStorage<SessionStorage extends AllStrings<SessionStorage>>(): TungstenSessionStorage<SessionStorage>;
61
+ export declare function makeSessionStorage<SessionStorage extends object>(options: WithDefaults<SessionStorage>): TungstenSessionStorage<SessionStorage, never>;
62
+ export declare function makeSessionStorage<SessionStorage extends object>(options: WithoutDefaults<SessionStorage>): TungstenSessionStorage<SessionStorage>;
63
+ export {};
26
64
  //# sourceMappingURL=browserStorage.d.ts.map