-
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support Session Storage and refactor the storage APIs (WebSQL will be…
… fixed soon)
- Loading branch information
Showing
6 changed files
with
123 additions
and
97 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,29 @@ | ||
import { type APIInterceptor, SupportEnum } from "$types/apiInterceptors"; | ||
|
||
import genStorageAPIInterceptors from "$util/storageAPIInterceptorsGeneric"; | ||
import { proxyLocation } from "$shared/proxyLocation"; | ||
|
||
export default genStorageAPIInterceptors("storage"); | ||
export default [ | ||
...genStorageAPIInterceptors("sharedStorage", $aero.sandbox.config.sharedStorageId), | ||
...genStorageAPIInterceptors("storage", $aero.sandbox.config.storageStoreId), | ||
...genStorageAPIInterceptors("sessionStorage", `${$aero.sandbox.config.sessionStoreId}_${$aero.clientId}`), | ||
// This is needed for Session Storage only | ||
{ | ||
init: () => { | ||
// Remove the keys from the previous sessions | ||
for (let i = 0; i < sessionStorage.length; i++) { | ||
const realKey = sessionStorage.key(i); | ||
if (realKey.startsWith(proxyLocation().origin)) { | ||
const keyWithoutOriginEscape = realKey.replace(new RegExp(`^${proxyLocation().origin}_`), ""); | ||
if ( | ||
// Is key from a previous session? | ||
keyWithoutOriginEscape.startsWith(`${$aero.sandbox.config.sessionStoreId}_`)) | ||
sessionStorage.removeItem(realKey); | ||
} | ||
} | ||
}, | ||
globalProp: "sessionStorage", | ||
forStorage: true, | ||
supports: SupportEnum.widelyAvailable | ||
} | ||
] as APIInterceptor[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,44 @@ | ||
import { type GeneratorCtxTypeProxyHandler } from "$types/apiInterceptors"; | ||
/** | ||
* Note: The cookie store ID is so that we can store data from other storage types when the storage is exhausted from them. We need to know what is actually a cookie. | ||
* @module | ||
*/ | ||
|
||
import { storagePrefix } from "$shared/storage"; | ||
|
||
const storageNomenclatureHandlers: { [key: string]: GeneratorCtxTypeProxyHandler } = { | ||
prefix: (ctx) => ({ | ||
apply: (target, that, args) => { | ||
const [key] = args; | ||
args[0] = prefixKey(ctx.cookieStoreId, key); | ||
return Reflect.apply(target, that, args); | ||
function genStorageNomenclatureHandlers(storeId): { [key: string]: ProxyHandler<Storage> } { | ||
return { | ||
prefix: { | ||
apply: (target, that, args) => { | ||
const [key] = args; | ||
args[0] = prefixKey(storeId, key); | ||
return Reflect.apply(target, that, args); | ||
} | ||
}, | ||
unprefix: { | ||
apply: (target, that, args) => { | ||
const [key] = args; | ||
args[0] = unprefixKey(storeId, key); | ||
return Reflect.apply(target, that, args); | ||
} | ||
} | ||
} as ProxyHandler<Storage>), | ||
unprefix: (ctx) => ({ | ||
apply: (target, that, args) => { | ||
const [key] = args; | ||
args[0] = unprefixKey(ctx.cookieStoreId, key); | ||
return Reflect.apply(target, that, args); | ||
} | ||
} as ProxyHandler<Storage>), | ||
}; | ||
} | ||
} | ||
|
||
|
||
function prefixKey(cookieStoreId, key: string): string { | ||
function prefixKey(prefix, key: string): string { | ||
let proxifiedKey = storagePrefix(key); | ||
if (cookieStoreId) { | ||
proxifiedKey = `${cookieStoreId}_${proxifiedKey}`; | ||
if (prefix) { | ||
proxifiedKey = `${prefix}_${proxifiedKey}`; | ||
} | ||
return proxifiedKey; | ||
} | ||
function unprefixKey(cookieStoreId, key: string): string { | ||
if (!key.startsWith(cookieStoreId)) | ||
$aero.logger.fatalErr("Failed to unprefix the key (the key does not belong to the current cookie store)"); | ||
const keyWithoutCookieStoreId = key.replace(new RegExp(`^${cookieStoreId}`), ""); | ||
if (!keyWithoutCookieStoreId.startsWith(storagePrefix(""))) | ||
$aero.logger.fatalErr("Failed to unprefix the key (the key does not have the storage prefix)"); | ||
return keyWithoutCookieStoreId.replace(storagePrefix(""), ""); | ||
/** Works for everything except Session Storage */ | ||
function unprefixKey(storeId: string, key: string): string { | ||
const storeIdKey = storagePrefix(storeId); | ||
if (!key.startsWith(storeIdKey)) | ||
$aero.logger.fatalErr(`Failed to unprefix the key (the key does not have the expected cookie store key prefix, "${storeIdKey}")!`); | ||
const keyWithoutStoreIdKey = key.replace(new RegExp(`^${storeIdKey}`), ""); | ||
return keyWithoutStoreIdKey; | ||
} | ||
|
||
export { storageNomenclatureHandlers }; | ||
export { genStorageNomenclatureHandlers, prefixKey, unprefixKey }; |
58 changes: 0 additions & 58 deletions
58
AeroSandbox/src/interceptors/util/storageAPIInterceptorsGeneric.ts
This file was deleted.
Oops, something went wrong.
59 changes: 59 additions & 0 deletions
59
AeroSandbox/src/interceptors/util/storageApiInterceptorsGeneric.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { type APIInterceptor, SupportEnum } from "$types/apiInterceptors.d.ts"; | ||
|
||
import { genStorageNomenclatureHandlers, unprefixKey } from "./storage"; | ||
import { storagePrefix } from "$shared/storage"; | ||
|
||
export default function genStorageApiInterceptors(key: string, storeId: string): APIInterceptor[] { | ||
const storageNomenclatureHandlers = genStorageNomenclatureHandlers(storeId); | ||
const storageAPIInterceptorsGeneric = [ | ||
{ | ||
proxyHandler: { | ||
apply(target, _that, _args) { | ||
const storageApi = key === "sessionStorage" ? localStorage : target; | ||
for (let i = 0; i < storageApi.length; i++) { | ||
const realKey = storageApi.key(i); | ||
const storeIdKey = storagePrefix(storeId); | ||
if (realKey.startsWith(storeIdKey)) | ||
storageApi.removeItem(realKey); | ||
} | ||
} | ||
} as ProxyHandler<Storage>, | ||
globalProp: ".clear" | ||
}, | ||
{ | ||
proxyHandler: storageNomenclatureHandlers.unprefix, | ||
globalProp: ".getItem" | ||
}, | ||
{ | ||
proxyHandler: { | ||
apply(target, _that, args) { | ||
const storageApi = key === "sessionStorage" ? localStorage : target; | ||
const [getIndex] = args; | ||
const proxifiedKeys: string[] = []; | ||
for (let i = 0; i < storageApi.length; i++) { | ||
const realKey = storageApi.key(i); | ||
const storeIdKey = storagePrefix(storeId); | ||
if (realKey.startsWith(storeIdKey)) | ||
proxifiedKeys.push(unprefixKey(storeId, realKey)); | ||
} | ||
return proxifiedKeys[getIndex]; | ||
} | ||
} as ProxyHandler<Storage>, | ||
globalProp: ".key" | ||
}, | ||
{ | ||
proxyHandler: storageNomenclatureHandlers.prefix, | ||
globalProp: ".setItem" | ||
}, | ||
{ | ||
proxyHandler: storageNomenclatureHandlers.unprefix, | ||
globalProp: ".removeItem" | ||
}, | ||
] as APIInterceptor[]; | ||
return storageAPIInterceptorsGeneric.map(apiInterceptor => { | ||
apiInterceptor.forStorage = true; | ||
apiInterceptor.globalProp = key + apiInterceptor.globalProp; | ||
apiInterceptor.supports = key === "sharedStorage" ? SupportEnum.shippingChromium | SupportEnum.draft : SupportEnum.widelyAvailable; | ||
return apiInterceptor; | ||
}); | ||
} |