edges-svelte 3.0.0 → 3.0.3

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.
@@ -6,7 +6,8 @@ const NULL_MARKER = '__EDGES_NULL__';
6
6
  const BIGINT_MARKER = '__EDGES_BIGINT__';
7
7
  const EDGES_STATE_FIELD = '__edges_state__';
8
8
  const EDGES_REV_FIELD = '__edges_rev__';
9
- let lastAppliedRevision = 0;
9
+ const SEEN_REVISIONS_LIMIT = 200;
10
+ const seenRevisions = new Set();
10
11
  const decodeEdgesValue = (value) => {
11
12
  if (value && typeof value === 'object') {
12
13
  if (UNDEFINED_MARKER in value)
@@ -26,6 +27,21 @@ const decodeEdgesValue = (value) => {
26
27
  }
27
28
  return value;
28
29
  };
30
+ const tryDecodeLegacyString = (value) => {
31
+ const trimmed = value.trim();
32
+ if (!(trimmed.startsWith('{') || trimmed.startsWith('['))) {
33
+ return value;
34
+ }
35
+ if (!trimmed.includes(UNDEFINED_MARKER) && !trimmed.includes(NULL_MARKER) && !trimmed.includes(BIGINT_MARKER)) {
36
+ return value;
37
+ }
38
+ try {
39
+ return decodeEdgesValue(JSON.parse(trimmed));
40
+ }
41
+ catch {
42
+ return value;
43
+ }
44
+ };
29
45
  export function registerStateUpdate(key, callback) {
30
46
  if (browser) {
31
47
  stateUpdateCallbacks.set(key, callback);
@@ -39,15 +55,7 @@ export function processEdgesState(edgesState) {
39
55
  window.__SAFE_SSR_STATE__ = store;
40
56
  batch(() => {
41
57
  for (const [key, value] of Object.entries(edgesState)) {
42
- let processedValue = decodeEdgesValue(value);
43
- if (typeof value === 'string') {
44
- try {
45
- processedValue = decodeEdgesValue(JSON.parse(value));
46
- }
47
- catch {
48
- /* do nothing */
49
- }
50
- }
58
+ const processedValue = typeof value === 'string' ? tryDecodeLegacyString(value) : decodeEdgesValue(value);
51
59
  store.set(key, processedValue);
52
60
  const callback = stateUpdateCallbacks.get(key);
53
61
  if (callback) {
@@ -63,11 +71,17 @@ export function applyEdgesFromPayload(payload) {
63
71
  const rawState = data[EDGES_STATE_FIELD];
64
72
  if (!rawState || typeof rawState !== 'object')
65
73
  return;
66
- const revision = Number(data[EDGES_REV_FIELD] ?? 0);
67
- if (Number.isFinite(revision) && revision > 0) {
68
- if (revision <= lastAppliedRevision)
74
+ const revision = data[EDGES_REV_FIELD];
75
+ if (typeof revision === 'string' && revision.length > 0) {
76
+ if (seenRevisions.has(revision))
69
77
  return;
70
- lastAppliedRevision = revision;
78
+ seenRevisions.add(revision);
79
+ if (seenRevisions.size > SEEN_REVISIONS_LIMIT) {
80
+ const oldestRevision = seenRevisions.values().next().value;
81
+ if (oldestRevision) {
82
+ seenRevisions.delete(oldestRevision);
83
+ }
84
+ }
71
85
  }
72
86
  processEdgesState(rawState);
73
87
  }
@@ -9,7 +9,7 @@ export interface ContextData {
9
9
  providersAutoKeyCounters?: Map<string, number>;
10
10
  providersConstructionStack?: string[];
11
11
  edgesDirtyKeys?: Set<string>;
12
- edgesRevision?: number;
12
+ edgesRevision?: string;
13
13
  } & App.ContextDataExtended;
14
14
  }
15
15
  declare class RequestContextManager {
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './provider/Provider.js';
2
2
  export { batch, transaction } from './utils/batch.js';
3
+ export { __withEdgesUniversalLoad } from './server/ServerSync.js';
3
4
  export type * from './types.js';
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './provider/Provider.js';
2
2
  export { batch, transaction } from './utils/batch.js';
3
+ export { __withEdgesUniversalLoad } from './server/ServerSync.js';
@@ -60,8 +60,9 @@ export function createEdgesPluginFactory(packageName, serverPath) {
60
60
  return `${beforeImports}\n${SYNC_MARKER}\n${importLine}\n${afterImports}`;
61
61
  };
62
62
  const ensureAstServerImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesServerLoad as ${AST_SERVER_LOAD_ALIAS}, __withEdgesActions as ${AST_ACTIONS_ALIAS} } from '${serverPath}';`);
63
- const ensureAstUniversalImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesUniversalLoad as ${AST_UNIVERSAL_LOAD_ALIAS} } from '${serverPath}';`);
64
- const ensureRegexImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesServerLoad, __withEdgesActions, __withEdgesUniversalLoad } from '${serverPath}';`);
63
+ const ensureAstUniversalImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesUniversalLoad as ${AST_UNIVERSAL_LOAD_ALIAS} } from '${packageName}';`);
64
+ const ensureRegexServerImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesServerLoad, __withEdgesActions } from '${serverPath}';`);
65
+ const ensureRegexUniversalImport = (sourceCode) => ensureSyncImport(sourceCode, `import { __withEdgesUniversalLoad } from '${packageName}';`);
65
66
  const findExportedLocal = (sourceFile, code, exportedName) => {
66
67
  const edits = [];
67
68
  let localName = null;
@@ -117,7 +118,7 @@ export function createEdgesPluginFactory(packageName, serverPath) {
117
118
  if (!LOAD_EXPORT_PATTERN.test(sourceCode) && !ACTIONS_EXPORT_PATTERN.test(sourceCode)) {
118
119
  return null;
119
120
  }
120
- let wrapped = ensureRegexImport(sourceCode);
121
+ let wrapped = ensureRegexServerImport(sourceCode);
121
122
  if (LOAD_EXPORT_PATTERN.test(wrapped)) {
122
123
  wrapped = wrapped
123
124
  .replace(LOAD_EXPORT_PATTERN, (match) => match.replace('export const load', 'const __userLoad'))
@@ -133,7 +134,7 @@ export function createEdgesPluginFactory(packageName, serverPath) {
133
134
  const wrapUniversalRouteModuleRegex = (sourceCode) => {
134
135
  if (!LOAD_EXPORT_PATTERN.test(sourceCode))
135
136
  return null;
136
- let wrapped = ensureRegexImport(sourceCode);
137
+ let wrapped = ensureRegexUniversalImport(sourceCode);
137
138
  wrapped = wrapped
138
139
  .replace(LOAD_EXPORT_PATTERN, (match) => match.replace('export const load', 'const __userUniversalLoad'))
139
140
  .concat('\n\nexport const load = __withEdgesUniversalLoad(__userUniversalLoad);');
@@ -1,14 +1,14 @@
1
1
  import { stateSerialize } from '../store/State.svelte.js';
2
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
+ import { randomUUID } from 'node:crypto';
3
4
  import { RequestContext } from '../context/Context.js';
4
5
  const storage = new AsyncLocalStorage();
5
- let requestRevision = 0;
6
6
  export const edgesHandle = async (event, callback, silentChromeDevtools = false) => {
7
7
  const requestSymbol = Symbol('request');
8
8
  return await storage.run({
9
9
  event: event,
10
10
  symbol: requestSymbol,
11
- data: { providers: new Map(), edgesDirtyKeys: new Set(), edgesRevision: ++requestRevision }
11
+ data: { providers: new Map(), edgesDirtyKeys: new Set(), edgesRevision: randomUUID() }
12
12
  }, async () => {
13
13
  RequestContext.init(() => {
14
14
  const context = storage.getStore();
@@ -34,7 +34,7 @@ const getEdgesDelta = () => {
34
34
  try {
35
35
  const context = RequestContext.current();
36
36
  const dirtyKeys = context.data.edgesDirtyKeys;
37
- const rev = context.data.edgesRevision ?? 0;
37
+ const rev = context.data.edgesRevision;
38
38
  const stateMap = getStateMap();
39
39
  if (!dirtyKeys || dirtyKeys.size === 0 || !stateMap || stateMap.size === 0)
40
40
  return undefined;
@@ -44,7 +44,7 @@ const getEdgesDelta = () => {
44
44
  continue;
45
45
  state[key] = encodeEdgesValue(stateMap.get(key));
46
46
  }
47
- if (Object.keys(state).length === 0)
47
+ if (!rev || Object.keys(state).length === 0)
48
48
  return undefined;
49
49
  return { state, rev };
50
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edges-svelte",
3
- "version": "3.0.0",
3
+ "version": "3.0.3",
4
4
  "license": "MIT",
5
5
  "author": "Pixel1917",
6
6
  "description": "A blazing-fast, extremely lightweight and SSR-friendly store for Svelte",