@junobuild/storage 0.0.7 → 0.0.8
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.
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +2 -2
- package/dist/declarations/console/console.did.d.ts +1 -0
- package/dist/declarations/console/console.factory.did.js +1 -0
- package/dist/declarations/console/console.factory.did.mjs +1 -0
- package/dist/declarations/satellite/satellite.did.d.ts +10 -1
- package/dist/declarations/satellite/satellite.factory.did.js +28 -19
- package/dist/declarations/satellite/satellite.factory.did.mjs +28 -19
- package/dist/node/index.mjs +1 -1
- package/dist/node/index.mjs.map +2 -2
- package/package.json +1 -1
package/dist/browser/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Principal as R}from"@dfinity/principal";var U=t=>t==null,k=t=>!U(t);var n=t=>k(t)?[t]:[];var _=()=>typeof window<"u";var B=async({asset:{data:t,filename:s,collection:o,headers:a,token:l,fullPath:i,encoding:b,description:A},actor:
|
|
1
|
+
import{Principal as R}from"@dfinity/principal";var U=t=>t==null,k=t=>!U(t);var n=t=>k(t)?[t]:[];var _=()=>typeof window<"u";var B=async({asset:{data:t,filename:s,collection:o,headers:a,token:l,fullPath:i,encoding:b,description:A},actor:c,init_asset_upload:C})=>{let{batch_id:p}=await C({collection:o,full_path:i,name:s,token:n(l),encoding_type:n(b),description:n(A)}),u=19e5,d=[],y=_()?new Blob([await t.arrayBuffer()]):t,f=0n;for(let e=0;e<y.size;e+=u){let m=y.slice(e,e+u);d.push({batchId:p,chunk:m,actor:c,orderId:f}),f++}let r=[];for await(let e of I({uploadChunks:d}))r=[...r,...e];let h=a.find(([e,m])=>e.toLowerCase()==="content-type")===void 0&&t.type!==void 0&&t.type!==""?[["Content-Type",t.type]]:void 0;await c.commit_asset_upload({batch_id:p,chunk_ids:r.map(({chunk_id:e})=>e),headers:[...a,...h||[]]})};async function*I({uploadChunks:t,limit:s=12}){for(let o=0;o<t.length;o=o+s){let a=t.slice(o,o+s);yield await Promise.all(a.map(i=>w(i)))}}var w=async({batchId:t,chunk:s,actor:o,orderId:a})=>o.upload_asset_chunk({batch_id:t,content:new Uint8Array(await s.arrayBuffer()),order_id:n(a)});export{B as uploadAsset};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../utils/src/utils/debounce.utils.ts", "../../../utils/src/utils/json.utils.ts", "../../../utils/src/utils/null.utils.ts", "../../../utils/src/utils/did.utils.ts", "../../../utils/src/utils/env.utils.ts", "../../src/api/storage.api.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Creates a debounced function that delays invoking the provided function until after the specified timeout.\n * @param {Function} func - The function to debounce.\n * @param {number} [timeout=300] - The number of milliseconds to delay. Defaults to 300ms if not specified or invalid.\n * @returns {Function} A debounced function.\n */\n/* eslint-disable-next-line @typescript-eslint/ban-types */\nexport const debounce = (func: Function, timeout?: number): Function => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n return (...args: unknown[]) => {\n const next = () => func(...args);\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(next, timeout !== undefined && timeout > 0 ? timeout : 300);\n };\n};\n", "import {Principal} from '@dfinity/principal';\nimport {nonNullish} from './null.utils';\n\nconst JSON_KEY_BIGINT = '__bigint__';\nconst JSON_KEY_PRINCIPAL = '__principal__';\nconst JSON_KEY_UINT8ARRAY = '__uint8array__';\n\n/**\n * A function that alters the behavior of the stringification process for BigInt, Principal, and Uint8Array.\n * @param {string} _key - The key of the value being stringified.\n * @param {unknown} value - The value being stringified.\n * @returns {unknown} The altered value for stringification.\n */\nexport const jsonReplacer = (_key: string, value: unknown): unknown => {\n if (typeof value === 'bigint') {\n return {[JSON_KEY_BIGINT]: `${value}`};\n }\n\n if (nonNullish(value) && value instanceof Principal) {\n return {[JSON_KEY_PRINCIPAL]: value.toText()};\n }\n\n if (nonNullish(value) && value instanceof Uint8Array) {\n return {[JSON_KEY_UINT8ARRAY]: Array.from(value)};\n }\n\n return value;\n};\n\n/**\n * A parser that interprets revived BigInt, Principal, and Uint8Array when constructing JavaScript values or objects.\n * @param {string} _key - The key of the value being parsed.\n * @param {unknown} value - The value being parsed.\n * @returns {unknown} The parsed value.\n */\nexport const jsonReviver = (_key: string, value: unknown): unknown => {\n const mapValue = <T>(key: string): T => (value as Record<string, T>)[key];\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_BIGINT in value) {\n return BigInt(mapValue(JSON_KEY_BIGINT));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_PRINCIPAL in value) {\n return Principal.fromText(mapValue(JSON_KEY_PRINCIPAL));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_UINT8ARRAY in value) {\n return Uint8Array.from(mapValue(JSON_KEY_UINT8ARRAY));\n }\n\n return value;\n};\n", "/**\n * Checks if the provided argument is null or undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is null or undefined, false otherwise.\n */\nexport const isNullish = <T>(argument: T | undefined | null): argument is undefined | null =>\n argument === null || argument === undefined;\n\n/**\n * Checks if the provided argument is neither null nor undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is neither null nor undefined, false otherwise.\n */\nexport const nonNullish = <T>(argument: T | undefined | null): argument is NonNullable<T> =>\n !isNullish(argument);\n\n/**\n * Represents an error thrown when a value is null or undefined.\n * @class\n * @extends {Error}\n */\nexport class NullishError extends Error {}\n\n/**\n * Asserts that a value is neither null nor undefined.\n * @template T\n * @param {T} value - The value to check.\n * @param {string} [message] - The optional error message to use if the assertion fails.\n * @throws {NullishError} If the value is null or undefined.\n * @returns {asserts value is NonNullable<T>} Asserts that the value is neither null nor undefined.\n */\nexport const assertNonNullish: <T>(\n value: T,\n message?: string\n) => asserts value is NonNullable<T> = <T>(value: T, message?: string): void => {\n if (isNullish(value)) {\n throw new NullishError(message);\n }\n};\n", "import {jsonReplacer, jsonReviver} from './json.utils';\nimport {nonNullish} from './null.utils';\n\n/**\n * Converts a value to a nullable array.\n * @template T\n * @param {T} [value] - The value to convert.\n * @returns {([] | [T])} A nullable array containing the value if non-nullish, or an empty array if nullish.\n */\nexport const toNullable = <T>(value?: T): [] | [T] => {\n return nonNullish(value) ? [value] : [];\n};\n\n/**\n * Extracts a value from a nullable array.\n * @template T\n * @param {([] | [T])} value - The nullable array.\n * @returns {(T | undefined)} The value if present, or undefined if the array is empty.\n */\nexport const fromNullable = <T>(value: [] | [T]): T | undefined => {\n return value?.[0];\n};\n\n/**\n * Converts data to a Uint8Array for transmission or storage.\n * @template T\n * @param {T} data - The data to convert.\n * @returns {Promise<Uint8Array>} A promise that resolves to a Uint8Array representation of the data.\n */\nexport const toArray = async <T>(data: T): Promise<Uint8Array> => {\n const blob: Blob = new Blob([JSON.stringify(data, jsonReplacer)], {\n type: 'application/json; charset=utf-8'\n });\n return new Uint8Array(await blob.arrayBuffer());\n};\n\n/**\n * Converts a Uint8Array or number array back to the original data type.\n * @template T\n * @param {(Uint8Array | number[])} data - The array to convert.\n * @returns {Promise<T>} A promise that resolves to the original data.\n */\nexport const fromArray = async <T>(data: Uint8Array | number[]): Promise<T> => {\n const blob: Blob = new Blob([data instanceof Uint8Array ? data : new Uint8Array(data)], {\n type: 'application/json; charset=utf-8'\n });\n return JSON.parse(await blob.text(), jsonReviver);\n};\n", "/**\n * Checks if the current environment is a browser.\n * @returns {boolean} True if the current environment is a browser, false otherwise.\n */\nexport const isBrowser = (): boolean => typeof window !== `undefined`;\n", "import {isBrowser, toNullable} from '@junobuild/utils';\nimport type {\n _SERVICE as ConsoleActor,\n InitAssetKey as ConsoleInitAssetKey,\n InitUploadResult as ConsoleInitUploadResult\n} from '../../declarations/console/console.did';\nimport type {\n _SERVICE as SatelliteActor,\n InitAssetKey as SatelliteInitAssetKey,\n InitUploadResult as SatelliteInitUploadResult\n} from '../../declarations/satellite/satellite.did';\nimport type {ENCODING_TYPE, Storage} from '../types/storage.types';\n\nexport type UploadAsset = Required<Omit<Storage, 'token' | 'encoding' | 'description'>> &\n Pick<Storage, 'token' | 'encoding' | 'description'>;\n\nexport const uploadAsset = async ({\n asset: {data, filename, collection, headers, token, fullPath, encoding, description},\n actor,\n init_asset_upload\n}: {\n asset: UploadAsset;\n actor: SatelliteActor | ConsoleActor;\n init_asset_upload: (\n initAssetKey: SatelliteInitAssetKey | ConsoleInitAssetKey\n ) => Promise<SatelliteInitUploadResult | ConsoleInitUploadResult>;\n}): Promise<void> => {\n const {batch_id: batchId} = await init_asset_upload({\n collection,\n full_path: fullPath,\n name: filename,\n token: toNullable<string>(token),\n encoding_type: toNullable<ENCODING_TYPE>(encoding),\n description: toNullable(description)\n });\n\n // https://forum.dfinity.org/t/optimal-upload-chunk-size/20444/23?u=peterparker\n const chunkSize = 1900000;\n\n const uploadChunks: UploadChunkParams[] = [];\n\n // Prevent transforming chunk to arrayBuffer error: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.\n const clone: Blob = isBrowser() ? new Blob([await data.arrayBuffer()]) : data;\n\n // Split data into chunks\n let orderId = 0n;\n for (let start = 0; start < clone.size; start += chunkSize) {\n const chunk: Blob = clone.slice(start, start + chunkSize);\n\n uploadChunks.push({\n batchId,\n chunk,\n actor,\n orderId\n });\n\n orderId++;\n }\n\n // Upload chunks to the IC in batch - i.e. 12 chunks uploaded at a time.\n let chunkIds: UploadChunkResult[] = [];\n for await (const results of batchUploadChunks({uploadChunks})) {\n chunkIds = [...chunkIds, ...results];\n }\n\n const contentType: [[string, string]] | undefined =\n headers.find(([type, _]) => type.toLowerCase() === 'content-type') === undefined &&\n data.type !== undefined &&\n data.type !== ''\n ? [['Content-Type', data.type]]\n : undefined;\n\n await actor.commit_asset_upload({\n batch_id: batchId,\n chunk_ids: chunkIds.map(({chunk_id}: UploadChunkResult) => chunk_id),\n headers: [...headers, ...(contentType ? contentType : [])]\n });\n};\n\nasync function* batchUploadChunks({\n uploadChunks,\n limit = 12\n}: {\n uploadChunks: UploadChunkParams[];\n limit?: number;\n}): AsyncGenerator<UploadChunkResult[], void> {\n for (let i = 0; i < uploadChunks.length; i = i + limit) {\n const batch = uploadChunks.slice(i, i + limit);\n const result = await Promise.all(batch.map((params) => uploadChunk(params)));\n yield result;\n }\n}\n\ntype UploadChunkResult = {chunk_id: bigint};\n\ntype UploadChunkParams = {\n batchId: bigint;\n chunk: Blob;\n actor: SatelliteActor | ConsoleActor;\n orderId: bigint;\n};\n\nconst uploadChunk = async ({\n batchId,\n chunk,\n actor,\n orderId\n}: UploadChunkParams): Promise<UploadChunkResult> =>\n actor.upload_asset_chunk({\n batch_id: batchId,\n content: new Uint8Array(await chunk.arrayBuffer()),\n order_id: toNullable(orderId)\n });\n"],
|
|
5
|
-
"mappings": "ACAA,OAAQ,aAAAA,MAAgB,
|
|
4
|
+
"sourcesContent": ["/**\n * Creates a debounced function that delays invoking the provided function until after the specified timeout.\n * @param {Function} func - The function to debounce.\n * @param {number} [timeout=300] - The number of milliseconds to delay. Defaults to 300ms if not specified or invalid.\n * @returns {Function} A debounced function.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types, local-rules/prefer-object-params\nexport const debounce = (func: Function, timeout?: number): Function => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n return (...args: unknown[]) => {\n const next = () => func(...args);\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(next, timeout !== undefined && timeout > 0 ? timeout : 300);\n };\n};\n", "import {Principal} from '@dfinity/principal';\nimport {nonNullish} from './null.utils';\n\nconst JSON_KEY_BIGINT = '__bigint__';\nconst JSON_KEY_PRINCIPAL = '__principal__';\nconst JSON_KEY_UINT8ARRAY = '__uint8array__';\n\n/**\n * A function that alters the behavior of the stringification process for BigInt, Principal, and Uint8Array.\n * @param {string} _key - The key of the value being stringified.\n * @param {unknown} value - The value being stringified.\n * @returns {unknown} The altered value for stringification.\n */\n// eslint-disable-next-line local-rules/prefer-object-params\nexport const jsonReplacer = (_key: string, value: unknown): unknown => {\n if (typeof value === 'bigint') {\n return {[JSON_KEY_BIGINT]: `${value}`};\n }\n\n if (nonNullish(value) && value instanceof Principal) {\n return {[JSON_KEY_PRINCIPAL]: value.toText()};\n }\n\n if (nonNullish(value) && value instanceof Uint8Array) {\n return {[JSON_KEY_UINT8ARRAY]: Array.from(value)};\n }\n\n return value;\n};\n\n/**\n * A parser that interprets revived BigInt, Principal, and Uint8Array when constructing JavaScript values or objects.\n * @param {string} _key - The key of the value being parsed.\n * @param {unknown} value - The value being parsed.\n * @returns {unknown} The parsed value.\n */\n// eslint-disable-next-line local-rules/prefer-object-params\nexport const jsonReviver = (_key: string, value: unknown): unknown => {\n const mapValue = <T>(key: string): T => (value as Record<string, T>)[key];\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_BIGINT in value) {\n return BigInt(mapValue(JSON_KEY_BIGINT));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_PRINCIPAL in value) {\n return Principal.fromText(mapValue(JSON_KEY_PRINCIPAL));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_UINT8ARRAY in value) {\n return Uint8Array.from(mapValue(JSON_KEY_UINT8ARRAY));\n }\n\n return value;\n};\n", "/**\n * Checks if the provided argument is null or undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is null or undefined, false otherwise.\n */\n// eslint-disable-next-line local-rules/use-option-type-wrapper\nexport const isNullish = <T>(argument: T | undefined | null): argument is undefined | null =>\n argument === null || argument === undefined;\n\n/**\n * Checks if the provided argument is neither null nor undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is neither null nor undefined, false otherwise.\n */\n// eslint-disable-next-line local-rules/use-option-type-wrapper\nexport const nonNullish = <T>(argument: T | undefined | null): argument is NonNullable<T> =>\n !isNullish(argument);\n\n/**\n * Represents an error thrown when a value is null or undefined.\n * @class\n * @extends {Error}\n */\nexport class NullishError extends Error {}\n\n/**\n * Asserts that a value is neither null nor undefined.\n * @template T\n * @param {T} value - The value to check.\n * @param {string} [message] - The optional error message to use if the assertion fails.\n * @throws {NullishError} If the value is null or undefined.\n * @returns {asserts value is NonNullable<T>} Asserts that the value is neither null nor undefined.\n */\nexport const assertNonNullish: <T>(\n value: T,\n message?: string\n // eslint-disable-next-line local-rules/prefer-object-params\n) => asserts value is NonNullable<T> = <T>(value: T, message?: string): void => {\n if (isNullish(value)) {\n throw new NullishError(message);\n }\n};\n", "import {jsonReplacer, jsonReviver} from './json.utils';\nimport {nonNullish} from './null.utils';\n\n/**\n * Converts a value to a nullable array.\n * @template T\n * @param {T} [value] - The value to convert.\n * @returns {([] | [T])} A nullable array containing the value if non-nullish, or an empty array if nullish.\n */\nexport const toNullable = <T>(value?: T): [] | [T] => (nonNullish(value) ? [value] : []);\n\n/**\n * Extracts a value from a nullable array.\n * @template T\n * @param {([] | [T])} value - The nullable array.\n * @returns {(T | undefined)} The value if present, or undefined if the array is empty.\n */\nexport const fromNullable = <T>(value: [] | [T]): T | undefined => value?.[0];\n\n/**\n * Converts data to a Uint8Array for transmission or storage.\n * @template T\n * @param {T} data - The data to convert.\n * @returns {Promise<Uint8Array>} A promise that resolves to a Uint8Array representation of the data.\n */\nexport const toArray = async <T>(data: T): Promise<Uint8Array> => {\n const blob: Blob = new Blob([JSON.stringify(data, jsonReplacer)], {\n type: 'application/json; charset=utf-8'\n });\n return new Uint8Array(await blob.arrayBuffer());\n};\n\n/**\n * Converts a Uint8Array or number array back to the original data type.\n * @template T\n * @param {(Uint8Array | number[])} data - The array to convert.\n * @returns {Promise<T>} A promise that resolves to the original data.\n */\nexport const fromArray = async <T>(data: Uint8Array | number[]): Promise<T> => {\n const blob: Blob = new Blob([data instanceof Uint8Array ? data : new Uint8Array(data)], {\n type: 'application/json; charset=utf-8'\n });\n return JSON.parse(await blob.text(), jsonReviver);\n};\n", "/**\n * Checks if the current environment is a browser.\n * @returns {boolean} True if the current environment is a browser, false otherwise.\n */\nexport const isBrowser = (): boolean => typeof window !== `undefined`;\n", "import {isBrowser, toNullable} from '@junobuild/utils';\nimport type {\n _SERVICE as ConsoleActor,\n InitAssetKey as ConsoleInitAssetKey,\n InitUploadResult as ConsoleInitUploadResult\n} from '../../declarations/console/console.did';\nimport type {\n _SERVICE as SatelliteActor,\n InitAssetKey as SatelliteInitAssetKey,\n InitUploadResult as SatelliteInitUploadResult\n} from '../../declarations/satellite/satellite.did';\nimport type {ENCODING_TYPE, Storage} from '../types/storage.types';\n\nexport type UploadAsset = Required<Omit<Storage, 'token' | 'encoding' | 'description'>> &\n Pick<Storage, 'token' | 'encoding' | 'description'>;\n\nexport const uploadAsset = async ({\n asset: {data, filename, collection, headers, token, fullPath, encoding, description},\n actor,\n init_asset_upload\n}: {\n asset: UploadAsset;\n actor: SatelliteActor | ConsoleActor;\n init_asset_upload: (\n initAssetKey: SatelliteInitAssetKey | ConsoleInitAssetKey\n ) => Promise<SatelliteInitUploadResult | ConsoleInitUploadResult>;\n}): Promise<void> => {\n const {batch_id: batchId} = await init_asset_upload({\n collection,\n full_path: fullPath,\n name: filename,\n token: toNullable<string>(token),\n encoding_type: toNullable<ENCODING_TYPE>(encoding),\n description: toNullable(description)\n });\n\n // https://forum.dfinity.org/t/optimal-upload-chunk-size/20444/23?u=peterparker\n const chunkSize = 1900000;\n\n const uploadChunks: UploadChunkParams[] = [];\n\n // Prevent transforming chunk to arrayBuffer error: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.\n const clone: Blob = isBrowser() ? new Blob([await data.arrayBuffer()]) : data;\n\n // Split data into chunks\n let orderId = 0n;\n for (let start = 0; start < clone.size; start += chunkSize) {\n const chunk: Blob = clone.slice(start, start + chunkSize);\n\n uploadChunks.push({\n batchId,\n chunk,\n actor,\n orderId\n });\n\n orderId++;\n }\n\n // Upload chunks to the IC in batch - i.e. 12 chunks uploaded at a time.\n let chunkIds: UploadChunkResult[] = [];\n for await (const results of batchUploadChunks({uploadChunks})) {\n chunkIds = [...chunkIds, ...results];\n }\n\n const contentType: [[string, string]] | undefined =\n headers.find(([type, _]) => type.toLowerCase() === 'content-type') === undefined &&\n data.type !== undefined &&\n data.type !== ''\n ? [['Content-Type', data.type]]\n : undefined;\n\n await actor.commit_asset_upload({\n batch_id: batchId,\n chunk_ids: chunkIds.map(({chunk_id}: UploadChunkResult) => chunk_id),\n headers: [...headers, ...(contentType ? contentType : [])]\n });\n};\n\nasync function* batchUploadChunks({\n uploadChunks,\n limit = 12\n}: {\n uploadChunks: UploadChunkParams[];\n limit?: number;\n}): AsyncGenerator<UploadChunkResult[], void> {\n for (let i = 0; i < uploadChunks.length; i = i + limit) {\n const batch = uploadChunks.slice(i, i + limit);\n const result = await Promise.all(batch.map((params) => uploadChunk(params)));\n yield result;\n }\n}\n\ninterface UploadChunkResult {\n chunk_id: bigint;\n}\n\ninterface UploadChunkParams {\n batchId: bigint;\n chunk: Blob;\n actor: SatelliteActor | ConsoleActor;\n orderId: bigint;\n}\n\nconst uploadChunk = async ({\n batchId,\n chunk,\n actor,\n orderId\n}: UploadChunkParams): Promise<UploadChunkResult> =>\n actor.upload_asset_chunk({\n batch_id: batchId,\n content: new Uint8Array(await chunk.arrayBuffer()),\n order_id: toNullable(orderId)\n });\n"],
|
|
5
|
+
"mappings": "ACAA,OAAQ,aAAAA,MAAgB,qBCOjB,IAAMC,EAAgBC,GAC3BA,GAAa,KASFC,EAAiBD,GAC5B,CAACD,EAAUC,CAAQ,ECTd,IAAME,EAAiBC,GAAyBC,EAAWD,CAAK,EAAI,CAACA,CAAK,EAAI,CAAC,ECL/E,IAAME,EAAY,IAAe,OAAO,OAAW,ICYnD,IAAMC,EAAc,MAAO,CAChC,MAAO,CAAC,KAAAC,EAAM,SAAAC,EAAU,WAAAC,EAAY,QAAAC,EAAS,MAAAC,EAAO,SAAAC,EAAU,SAAAC,EAAU,YAAAC,CAAW,EACnF,MAAAC,EACA,kBAAAC,CACF,IAMqB,CACnB,GAAM,CAAC,SAAUC,CAAO,EAAI,MAAMD,EAAkB,CAClD,WAAAP,EACA,UAAWG,EACX,KAAMJ,EACN,MAAOU,EAAmBP,CAAK,EAC/B,cAAeO,EAA0BL,CAAQ,EACjD,YAAaK,EAAWJ,CAAW,CACrC,CAAC,EAGKK,EAAY,KAEZC,EAAoC,CAAC,EAGrCC,EAAcC,EAAU,EAAI,IAAI,KAAK,CAAC,MAAMf,EAAK,YAAY,CAAC,CAAC,EAAIA,EAGrEgB,EAAU,GACd,QAASC,EAAQ,EAAGA,EAAQH,EAAM,KAAMG,GAASL,EAAW,CAC1D,IAAMM,EAAcJ,EAAM,MAAMG,EAAOA,EAAQL,CAAS,EAExDC,EAAa,KAAK,CAChB,QAAAH,EACA,MAAAQ,EACA,MAAAV,EACA,QAAAQ,CACF,CAAC,EAEDA,GACF,CAGA,IAAIG,EAAgC,CAAC,EACrC,cAAiBC,KAAWC,EAAkB,CAAC,aAAAR,CAAY,CAAC,EAC1DM,EAAW,CAAC,GAAGA,EAAU,GAAGC,CAAO,EAGrC,IAAME,EACJnB,EAAQ,KAAK,CAAC,CAACoB,EAAMC,CAAC,IAAMD,EAAK,YAAY,IAAM,cAAc,IAAM,QACvEvB,EAAK,OAAS,QACdA,EAAK,OAAS,GACV,CAAC,CAAC,eAAgBA,EAAK,IAAI,CAAC,EAC5B,OAEN,MAAMQ,EAAM,oBAAoB,CAC9B,SAAUE,EACV,UAAWS,EAAS,IAAI,CAAC,CAAC,SAAAM,CAAQ,IAAyBA,CAAQ,EACnE,QAAS,CAAC,GAAGtB,EAAS,GAAImB,GAA4B,CAAC,CAAE,CAC3D,CAAC,CACH,EAEA,eAAgBD,EAAkB,CAChC,aAAAR,EACA,MAAAa,EAAQ,EACV,EAG8C,CAC5C,QAASC,EAAI,EAAGA,EAAId,EAAa,OAAQc,EAAIA,EAAID,EAAO,CACtD,IAAME,EAAQf,EAAa,MAAMc,EAAGA,EAAID,CAAK,EAE7C,MADe,MAAM,QAAQ,IAAIE,EAAM,IAAKC,GAAWC,EAAYD,CAAM,CAAC,CAAC,CAE7E,CACF,CAaA,IAAMC,EAAc,MAAO,CACzB,QAAApB,EACA,MAAAQ,EACA,MAAAV,EACA,QAAAQ,CACF,IACER,EAAM,mBAAmB,CACvB,SAAUE,EACV,QAAS,IAAI,WAAW,MAAMQ,EAAM,YAAY,CAAC,EACjD,SAAUP,EAAWK,CAAO,CAC9B,CAAC",
|
|
6
6
|
"names": ["Principal", "isNullish", "argument", "nonNullish", "toNullable", "value", "nonNullish", "isBrowser", "uploadAsset", "data", "filename", "collection", "headers", "token", "fullPath", "encoding", "description", "actor", "init_asset_upload", "batchId", "g", "chunkSize", "uploadChunks", "clone", "h", "orderId", "start", "chunk", "chunkIds", "results", "batchUploadChunks", "contentType", "type", "_", "chunk_id", "limit", "i", "batch", "params", "uploadChunk"]
|
|
7
7
|
}
|
|
@@ -49,6 +49,7 @@ export interface ConfigMaxMemorySize {
|
|
|
49
49
|
export type ControllerScope = {Write: null} | {Admin: null};
|
|
50
50
|
export interface CreateCanisterArgs {
|
|
51
51
|
block_index: [] | [bigint];
|
|
52
|
+
subnet_id: [] | [Principal];
|
|
52
53
|
user: Principal;
|
|
53
54
|
}
|
|
54
55
|
export interface CustomDomain {
|
|
@@ -146,6 +146,10 @@ export interface MemorySize {
|
|
|
146
146
|
heap: bigint;
|
|
147
147
|
}
|
|
148
148
|
export type Permission = {Controllers: null} | {Private: null} | {Public: null} | {Managed: null};
|
|
149
|
+
export interface RateConfig {
|
|
150
|
+
max_tokens: bigint;
|
|
151
|
+
time_per_token_ns: bigint;
|
|
152
|
+
}
|
|
149
153
|
export interface Rule {
|
|
150
154
|
max_capacity: [] | [number];
|
|
151
155
|
memory: [] | [Memory];
|
|
@@ -155,6 +159,7 @@ export interface Rule {
|
|
|
155
159
|
created_at: bigint;
|
|
156
160
|
version: [] | [bigint];
|
|
157
161
|
mutable_permissions: [] | [boolean];
|
|
162
|
+
rate_config: [] | [RateConfig];
|
|
158
163
|
write: Permission;
|
|
159
164
|
}
|
|
160
165
|
export type RulesType = {Db: null} | {Storage: null};
|
|
@@ -179,6 +184,7 @@ export interface SetRule {
|
|
|
179
184
|
read: Permission;
|
|
180
185
|
version: [] | [bigint];
|
|
181
186
|
mutable_permissions: [] | [boolean];
|
|
187
|
+
rate_config: [] | [RateConfig];
|
|
182
188
|
write: Permission;
|
|
183
189
|
}
|
|
184
190
|
export interface StorageConfig {
|
|
@@ -240,6 +246,8 @@ export interface _SERVICE {
|
|
|
240
246
|
del_custom_domain: ActorMethod<[string], undefined>;
|
|
241
247
|
del_doc: ActorMethod<[string, string, DelDoc], undefined>;
|
|
242
248
|
del_docs: ActorMethod<[string], undefined>;
|
|
249
|
+
del_filtered_assets: ActorMethod<[string, ListParams], undefined>;
|
|
250
|
+
del_filtered_docs: ActorMethod<[string, ListParams], undefined>;
|
|
243
251
|
del_many_assets: ActorMethod<[Array<[string, string]>], undefined>;
|
|
244
252
|
del_many_docs: ActorMethod<[Array<[string, string, DelDoc]>], undefined>;
|
|
245
253
|
del_rule: ActorMethod<[RulesType, string, DelRule], undefined>;
|
|
@@ -251,6 +259,7 @@ export interface _SERVICE {
|
|
|
251
259
|
get_doc: ActorMethod<[string, string], [] | [Doc]>;
|
|
252
260
|
get_many_assets: ActorMethod<[Array<[string, string]>], Array<[string, [] | [AssetNoContent]]>>;
|
|
253
261
|
get_many_docs: ActorMethod<[Array<[string, string]>], Array<[string, [] | [Doc]]>>;
|
|
262
|
+
get_rule: ActorMethod<[RulesType, string], [] | [Rule]>;
|
|
254
263
|
get_storage_config: ActorMethod<[], StorageConfig>;
|
|
255
264
|
http_request: ActorMethod<[HttpRequest], HttpResponse>;
|
|
256
265
|
http_request_streaming_callback: ActorMethod<
|
|
@@ -270,7 +279,7 @@ export interface _SERVICE {
|
|
|
270
279
|
set_db_config: ActorMethod<[DbConfig], undefined>;
|
|
271
280
|
set_doc: ActorMethod<[string, string, SetDoc], Doc>;
|
|
272
281
|
set_many_docs: ActorMethod<[Array<[string, string, SetDoc]>], Array<[string, Doc]>>;
|
|
273
|
-
set_rule: ActorMethod<[RulesType, string, SetRule],
|
|
282
|
+
set_rule: ActorMethod<[RulesType, string, SetRule], Rule>;
|
|
274
283
|
set_storage_config: ActorMethod<[StorageConfig], undefined>;
|
|
275
284
|
upload_asset_chunk: ActorMethod<[UploadChunk], UploadChunkResult>;
|
|
276
285
|
version: ActorMethod<[], string>;
|
|
@@ -122,6 +122,29 @@ export const idlFactory = ({IDL}) => {
|
|
|
122
122
|
created_at: IDL.Nat64,
|
|
123
123
|
version: IDL.Opt(IDL.Nat64)
|
|
124
124
|
});
|
|
125
|
+
const Memory = IDL.Variant({Heap: IDL.Null, Stable: IDL.Null});
|
|
126
|
+
const Permission = IDL.Variant({
|
|
127
|
+
Controllers: IDL.Null,
|
|
128
|
+
Private: IDL.Null,
|
|
129
|
+
Public: IDL.Null,
|
|
130
|
+
Managed: IDL.Null
|
|
131
|
+
});
|
|
132
|
+
const RateConfig = IDL.Record({
|
|
133
|
+
max_tokens: IDL.Nat64,
|
|
134
|
+
time_per_token_ns: IDL.Nat64
|
|
135
|
+
});
|
|
136
|
+
const Rule = IDL.Record({
|
|
137
|
+
max_capacity: IDL.Opt(IDL.Nat32),
|
|
138
|
+
memory: IDL.Opt(Memory),
|
|
139
|
+
updated_at: IDL.Nat64,
|
|
140
|
+
max_size: IDL.Opt(IDL.Nat),
|
|
141
|
+
read: Permission,
|
|
142
|
+
created_at: IDL.Nat64,
|
|
143
|
+
version: IDL.Opt(IDL.Nat64),
|
|
144
|
+
mutable_permissions: IDL.Opt(IDL.Bool),
|
|
145
|
+
rate_config: IDL.Opt(RateConfig),
|
|
146
|
+
write: Permission
|
|
147
|
+
});
|
|
125
148
|
const HttpRequest = IDL.Record({
|
|
126
149
|
url: IDL.Text,
|
|
127
150
|
method: IDL.Text,
|
|
@@ -129,7 +152,6 @@ export const idlFactory = ({IDL}) => {
|
|
|
129
152
|
headers: IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
|
|
130
153
|
certificate_version: IDL.Opt(IDL.Nat16)
|
|
131
154
|
});
|
|
132
|
-
const Memory = IDL.Variant({Heap: IDL.Null, Stable: IDL.Null});
|
|
133
155
|
const StreamingCallbackToken = IDL.Record({
|
|
134
156
|
memory: Memory,
|
|
135
157
|
token: IDL.Opt(IDL.Text),
|
|
@@ -184,23 +206,6 @@ export const idlFactory = ({IDL}) => {
|
|
|
184
206
|
items: IDL.Vec(IDL.Tuple(IDL.Text, Doc)),
|
|
185
207
|
items_length: IDL.Nat64
|
|
186
208
|
});
|
|
187
|
-
const Permission = IDL.Variant({
|
|
188
|
-
Controllers: IDL.Null,
|
|
189
|
-
Private: IDL.Null,
|
|
190
|
-
Public: IDL.Null,
|
|
191
|
-
Managed: IDL.Null
|
|
192
|
-
});
|
|
193
|
-
const Rule = IDL.Record({
|
|
194
|
-
max_capacity: IDL.Opt(IDL.Nat32),
|
|
195
|
-
memory: IDL.Opt(Memory),
|
|
196
|
-
updated_at: IDL.Nat64,
|
|
197
|
-
max_size: IDL.Opt(IDL.Nat),
|
|
198
|
-
read: Permission,
|
|
199
|
-
created_at: IDL.Nat64,
|
|
200
|
-
version: IDL.Opt(IDL.Nat64),
|
|
201
|
-
mutable_permissions: IDL.Opt(IDL.Bool),
|
|
202
|
-
write: Permission
|
|
203
|
-
});
|
|
204
209
|
const MemorySize = IDL.Record({stable: IDL.Nat64, heap: IDL.Nat64});
|
|
205
210
|
const SetController = IDL.Record({
|
|
206
211
|
metadata: IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
|
|
@@ -223,6 +228,7 @@ export const idlFactory = ({IDL}) => {
|
|
|
223
228
|
read: Permission,
|
|
224
229
|
version: IDL.Opt(IDL.Nat64),
|
|
225
230
|
mutable_permissions: IDL.Opt(IDL.Bool),
|
|
231
|
+
rate_config: IDL.Opt(RateConfig),
|
|
226
232
|
write: Permission
|
|
227
233
|
});
|
|
228
234
|
const UploadChunk = IDL.Record({
|
|
@@ -248,6 +254,8 @@ export const idlFactory = ({IDL}) => {
|
|
|
248
254
|
del_custom_domain: IDL.Func([IDL.Text], [], []),
|
|
249
255
|
del_doc: IDL.Func([IDL.Text, IDL.Text, DelDoc], [], []),
|
|
250
256
|
del_docs: IDL.Func([IDL.Text], [], []),
|
|
257
|
+
del_filtered_assets: IDL.Func([IDL.Text, ListParams], [], []),
|
|
258
|
+
del_filtered_docs: IDL.Func([IDL.Text, ListParams], [], []),
|
|
251
259
|
del_many_assets: IDL.Func([IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text))], [], []),
|
|
252
260
|
del_many_docs: IDL.Func([IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text, DelDoc))], [], []),
|
|
253
261
|
del_rule: IDL.Func([RulesType, IDL.Text, DelRule], [], []),
|
|
@@ -267,6 +275,7 @@ export const idlFactory = ({IDL}) => {
|
|
|
267
275
|
[IDL.Vec(IDL.Tuple(IDL.Text, IDL.Opt(Doc)))],
|
|
268
276
|
['query']
|
|
269
277
|
),
|
|
278
|
+
get_rule: IDL.Func([RulesType, IDL.Text], [IDL.Opt(Rule)], ['query']),
|
|
270
279
|
get_storage_config: IDL.Func([], [StorageConfig], ['query']),
|
|
271
280
|
http_request: IDL.Func([HttpRequest], [HttpResponse], ['query']),
|
|
272
281
|
http_request_streaming_callback: IDL.Func(
|
|
@@ -295,7 +304,7 @@ export const idlFactory = ({IDL}) => {
|
|
|
295
304
|
[IDL.Vec(IDL.Tuple(IDL.Text, Doc))],
|
|
296
305
|
[]
|
|
297
306
|
),
|
|
298
|
-
set_rule: IDL.Func([RulesType, IDL.Text, SetRule], [], []),
|
|
307
|
+
set_rule: IDL.Func([RulesType, IDL.Text, SetRule], [Rule], []),
|
|
299
308
|
set_storage_config: IDL.Func([StorageConfig], [], []),
|
|
300
309
|
upload_asset_chunk: IDL.Func([UploadChunk], [UploadChunkResult], []),
|
|
301
310
|
version: IDL.Func([], [IDL.Text], ['query'])
|
|
@@ -122,6 +122,29 @@ export const idlFactory = ({IDL}) => {
|
|
|
122
122
|
created_at: IDL.Nat64,
|
|
123
123
|
version: IDL.Opt(IDL.Nat64)
|
|
124
124
|
});
|
|
125
|
+
const Memory = IDL.Variant({Heap: IDL.Null, Stable: IDL.Null});
|
|
126
|
+
const Permission = IDL.Variant({
|
|
127
|
+
Controllers: IDL.Null,
|
|
128
|
+
Private: IDL.Null,
|
|
129
|
+
Public: IDL.Null,
|
|
130
|
+
Managed: IDL.Null
|
|
131
|
+
});
|
|
132
|
+
const RateConfig = IDL.Record({
|
|
133
|
+
max_tokens: IDL.Nat64,
|
|
134
|
+
time_per_token_ns: IDL.Nat64
|
|
135
|
+
});
|
|
136
|
+
const Rule = IDL.Record({
|
|
137
|
+
max_capacity: IDL.Opt(IDL.Nat32),
|
|
138
|
+
memory: IDL.Opt(Memory),
|
|
139
|
+
updated_at: IDL.Nat64,
|
|
140
|
+
max_size: IDL.Opt(IDL.Nat),
|
|
141
|
+
read: Permission,
|
|
142
|
+
created_at: IDL.Nat64,
|
|
143
|
+
version: IDL.Opt(IDL.Nat64),
|
|
144
|
+
mutable_permissions: IDL.Opt(IDL.Bool),
|
|
145
|
+
rate_config: IDL.Opt(RateConfig),
|
|
146
|
+
write: Permission
|
|
147
|
+
});
|
|
125
148
|
const HttpRequest = IDL.Record({
|
|
126
149
|
url: IDL.Text,
|
|
127
150
|
method: IDL.Text,
|
|
@@ -129,7 +152,6 @@ export const idlFactory = ({IDL}) => {
|
|
|
129
152
|
headers: IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
|
|
130
153
|
certificate_version: IDL.Opt(IDL.Nat16)
|
|
131
154
|
});
|
|
132
|
-
const Memory = IDL.Variant({Heap: IDL.Null, Stable: IDL.Null});
|
|
133
155
|
const StreamingCallbackToken = IDL.Record({
|
|
134
156
|
memory: Memory,
|
|
135
157
|
token: IDL.Opt(IDL.Text),
|
|
@@ -184,23 +206,6 @@ export const idlFactory = ({IDL}) => {
|
|
|
184
206
|
items: IDL.Vec(IDL.Tuple(IDL.Text, Doc)),
|
|
185
207
|
items_length: IDL.Nat64
|
|
186
208
|
});
|
|
187
|
-
const Permission = IDL.Variant({
|
|
188
|
-
Controllers: IDL.Null,
|
|
189
|
-
Private: IDL.Null,
|
|
190
|
-
Public: IDL.Null,
|
|
191
|
-
Managed: IDL.Null
|
|
192
|
-
});
|
|
193
|
-
const Rule = IDL.Record({
|
|
194
|
-
max_capacity: IDL.Opt(IDL.Nat32),
|
|
195
|
-
memory: IDL.Opt(Memory),
|
|
196
|
-
updated_at: IDL.Nat64,
|
|
197
|
-
max_size: IDL.Opt(IDL.Nat),
|
|
198
|
-
read: Permission,
|
|
199
|
-
created_at: IDL.Nat64,
|
|
200
|
-
version: IDL.Opt(IDL.Nat64),
|
|
201
|
-
mutable_permissions: IDL.Opt(IDL.Bool),
|
|
202
|
-
write: Permission
|
|
203
|
-
});
|
|
204
209
|
const MemorySize = IDL.Record({stable: IDL.Nat64, heap: IDL.Nat64});
|
|
205
210
|
const SetController = IDL.Record({
|
|
206
211
|
metadata: IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
|
|
@@ -223,6 +228,7 @@ export const idlFactory = ({IDL}) => {
|
|
|
223
228
|
read: Permission,
|
|
224
229
|
version: IDL.Opt(IDL.Nat64),
|
|
225
230
|
mutable_permissions: IDL.Opt(IDL.Bool),
|
|
231
|
+
rate_config: IDL.Opt(RateConfig),
|
|
226
232
|
write: Permission
|
|
227
233
|
});
|
|
228
234
|
const UploadChunk = IDL.Record({
|
|
@@ -248,6 +254,8 @@ export const idlFactory = ({IDL}) => {
|
|
|
248
254
|
del_custom_domain: IDL.Func([IDL.Text], [], []),
|
|
249
255
|
del_doc: IDL.Func([IDL.Text, IDL.Text, DelDoc], [], []),
|
|
250
256
|
del_docs: IDL.Func([IDL.Text], [], []),
|
|
257
|
+
del_filtered_assets: IDL.Func([IDL.Text, ListParams], [], []),
|
|
258
|
+
del_filtered_docs: IDL.Func([IDL.Text, ListParams], [], []),
|
|
251
259
|
del_many_assets: IDL.Func([IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text))], [], []),
|
|
252
260
|
del_many_docs: IDL.Func([IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text, DelDoc))], [], []),
|
|
253
261
|
del_rule: IDL.Func([RulesType, IDL.Text, DelRule], [], []),
|
|
@@ -267,6 +275,7 @@ export const idlFactory = ({IDL}) => {
|
|
|
267
275
|
[IDL.Vec(IDL.Tuple(IDL.Text, IDL.Opt(Doc)))],
|
|
268
276
|
['query']
|
|
269
277
|
),
|
|
278
|
+
get_rule: IDL.Func([RulesType, IDL.Text], [IDL.Opt(Rule)], ['query']),
|
|
270
279
|
get_storage_config: IDL.Func([], [StorageConfig], ['query']),
|
|
271
280
|
http_request: IDL.Func([HttpRequest], [HttpResponse], ['query']),
|
|
272
281
|
http_request_streaming_callback: IDL.Func(
|
|
@@ -295,7 +304,7 @@ export const idlFactory = ({IDL}) => {
|
|
|
295
304
|
[IDL.Vec(IDL.Tuple(IDL.Text, Doc))],
|
|
296
305
|
[]
|
|
297
306
|
),
|
|
298
|
-
set_rule: IDL.Func([RulesType, IDL.Text, SetRule], [], []),
|
|
307
|
+
set_rule: IDL.Func([RulesType, IDL.Text, SetRule], [Rule], []),
|
|
299
308
|
set_storage_config: IDL.Func([StorageConfig], [], []),
|
|
300
309
|
upload_asset_chunk: IDL.Func([UploadChunk], [UploadChunkResult], []),
|
|
301
310
|
version: IDL.Func([], [IDL.Text], ['query'])
|
package/dist/node/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { createRequire as topLevelCreateRequire } from 'module';
|
|
2
2
|
const require = topLevelCreateRequire(import.meta.url);
|
|
3
|
-
import{Principal as R}from"@dfinity/principal";var U=t=>t==null,k=t=>!U(t);var n=t=>k(t)?[t]:[];var _=()=>typeof window<"u";var B=async({asset:{data:t,filename:s,collection:o,headers:a,token:l,fullPath:i,encoding:b,description:A},actor:
|
|
3
|
+
import{Principal as R}from"@dfinity/principal";var U=t=>t==null,k=t=>!U(t);var n=t=>k(t)?[t]:[];var _=()=>typeof window<"u";var B=async({asset:{data:t,filename:s,collection:o,headers:a,token:l,fullPath:i,encoding:b,description:A},actor:c,init_asset_upload:C})=>{let{batch_id:p}=await C({collection:o,full_path:i,name:s,token:n(l),encoding_type:n(b),description:n(A)}),u=19e5,d=[],y=_()?new Blob([await t.arrayBuffer()]):t,f=0n;for(let e=0;e<y.size;e+=u){let m=y.slice(e,e+u);d.push({batchId:p,chunk:m,actor:c,orderId:f}),f++}let r=[];for await(let e of I({uploadChunks:d}))r=[...r,...e];let h=a.find(([e,m])=>e.toLowerCase()==="content-type")===void 0&&t.type!==void 0&&t.type!==""?[["Content-Type",t.type]]:void 0;await c.commit_asset_upload({batch_id:p,chunk_ids:r.map(({chunk_id:e})=>e),headers:[...a,...h||[]]})};async function*I({uploadChunks:t,limit:s=12}){for(let o=0;o<t.length;o=o+s){let a=t.slice(o,o+s);yield await Promise.all(a.map(i=>w(i)))}}var w=async({batchId:t,chunk:s,actor:o,orderId:a})=>o.upload_asset_chunk({batch_id:t,content:new Uint8Array(await s.arrayBuffer()),order_id:n(a)});export{B as uploadAsset};
|
|
4
4
|
//# sourceMappingURL=index.mjs.map
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../utils/src/utils/debounce.utils.ts", "../../../utils/src/utils/json.utils.ts", "../../../utils/src/utils/null.utils.ts", "../../../utils/src/utils/did.utils.ts", "../../../utils/src/utils/env.utils.ts", "../../src/api/storage.api.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Creates a debounced function that delays invoking the provided function until after the specified timeout.\n * @param {Function} func - The function to debounce.\n * @param {number} [timeout=300] - The number of milliseconds to delay. Defaults to 300ms if not specified or invalid.\n * @returns {Function} A debounced function.\n */\n/* eslint-disable-next-line @typescript-eslint/ban-types */\nexport const debounce = (func: Function, timeout?: number): Function => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n return (...args: unknown[]) => {\n const next = () => func(...args);\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(next, timeout !== undefined && timeout > 0 ? timeout : 300);\n };\n};\n", "import {Principal} from '@dfinity/principal';\nimport {nonNullish} from './null.utils';\n\nconst JSON_KEY_BIGINT = '__bigint__';\nconst JSON_KEY_PRINCIPAL = '__principal__';\nconst JSON_KEY_UINT8ARRAY = '__uint8array__';\n\n/**\n * A function that alters the behavior of the stringification process for BigInt, Principal, and Uint8Array.\n * @param {string} _key - The key of the value being stringified.\n * @param {unknown} value - The value being stringified.\n * @returns {unknown} The altered value for stringification.\n */\nexport const jsonReplacer = (_key: string, value: unknown): unknown => {\n if (typeof value === 'bigint') {\n return {[JSON_KEY_BIGINT]: `${value}`};\n }\n\n if (nonNullish(value) && value instanceof Principal) {\n return {[JSON_KEY_PRINCIPAL]: value.toText()};\n }\n\n if (nonNullish(value) && value instanceof Uint8Array) {\n return {[JSON_KEY_UINT8ARRAY]: Array.from(value)};\n }\n\n return value;\n};\n\n/**\n * A parser that interprets revived BigInt, Principal, and Uint8Array when constructing JavaScript values or objects.\n * @param {string} _key - The key of the value being parsed.\n * @param {unknown} value - The value being parsed.\n * @returns {unknown} The parsed value.\n */\nexport const jsonReviver = (_key: string, value: unknown): unknown => {\n const mapValue = <T>(key: string): T => (value as Record<string, T>)[key];\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_BIGINT in value) {\n return BigInt(mapValue(JSON_KEY_BIGINT));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_PRINCIPAL in value) {\n return Principal.fromText(mapValue(JSON_KEY_PRINCIPAL));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_UINT8ARRAY in value) {\n return Uint8Array.from(mapValue(JSON_KEY_UINT8ARRAY));\n }\n\n return value;\n};\n", "/**\n * Checks if the provided argument is null or undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is null or undefined, false otherwise.\n */\nexport const isNullish = <T>(argument: T | undefined | null): argument is undefined | null =>\n argument === null || argument === undefined;\n\n/**\n * Checks if the provided argument is neither null nor undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is neither null nor undefined, false otherwise.\n */\nexport const nonNullish = <T>(argument: T | undefined | null): argument is NonNullable<T> =>\n !isNullish(argument);\n\n/**\n * Represents an error thrown when a value is null or undefined.\n * @class\n * @extends {Error}\n */\nexport class NullishError extends Error {}\n\n/**\n * Asserts that a value is neither null nor undefined.\n * @template T\n * @param {T} value - The value to check.\n * @param {string} [message] - The optional error message to use if the assertion fails.\n * @throws {NullishError} If the value is null or undefined.\n * @returns {asserts value is NonNullable<T>} Asserts that the value is neither null nor undefined.\n */\nexport const assertNonNullish: <T>(\n value: T,\n message?: string\n) => asserts value is NonNullable<T> = <T>(value: T, message?: string): void => {\n if (isNullish(value)) {\n throw new NullishError(message);\n }\n};\n", "import {jsonReplacer, jsonReviver} from './json.utils';\nimport {nonNullish} from './null.utils';\n\n/**\n * Converts a value to a nullable array.\n * @template T\n * @param {T} [value] - The value to convert.\n * @returns {([] | [T])} A nullable array containing the value if non-nullish, or an empty array if nullish.\n */\nexport const toNullable = <T>(value?: T): [] | [T] => {\n return nonNullish(value) ? [value] : [];\n};\n\n/**\n * Extracts a value from a nullable array.\n * @template T\n * @param {([] | [T])} value - The nullable array.\n * @returns {(T | undefined)} The value if present, or undefined if the array is empty.\n */\nexport const fromNullable = <T>(value: [] | [T]): T | undefined => {\n return value?.[0];\n};\n\n/**\n * Converts data to a Uint8Array for transmission or storage.\n * @template T\n * @param {T} data - The data to convert.\n * @returns {Promise<Uint8Array>} A promise that resolves to a Uint8Array representation of the data.\n */\nexport const toArray = async <T>(data: T): Promise<Uint8Array> => {\n const blob: Blob = new Blob([JSON.stringify(data, jsonReplacer)], {\n type: 'application/json; charset=utf-8'\n });\n return new Uint8Array(await blob.arrayBuffer());\n};\n\n/**\n * Converts a Uint8Array or number array back to the original data type.\n * @template T\n * @param {(Uint8Array | number[])} data - The array to convert.\n * @returns {Promise<T>} A promise that resolves to the original data.\n */\nexport const fromArray = async <T>(data: Uint8Array | number[]): Promise<T> => {\n const blob: Blob = new Blob([data instanceof Uint8Array ? data : new Uint8Array(data)], {\n type: 'application/json; charset=utf-8'\n });\n return JSON.parse(await blob.text(), jsonReviver);\n};\n", "/**\n * Checks if the current environment is a browser.\n * @returns {boolean} True if the current environment is a browser, false otherwise.\n */\nexport const isBrowser = (): boolean => typeof window !== `undefined`;\n", "import {isBrowser, toNullable} from '@junobuild/utils';\nimport type {\n _SERVICE as ConsoleActor,\n InitAssetKey as ConsoleInitAssetKey,\n InitUploadResult as ConsoleInitUploadResult\n} from '../../declarations/console/console.did';\nimport type {\n _SERVICE as SatelliteActor,\n InitAssetKey as SatelliteInitAssetKey,\n InitUploadResult as SatelliteInitUploadResult\n} from '../../declarations/satellite/satellite.did';\nimport type {ENCODING_TYPE, Storage} from '../types/storage.types';\n\nexport type UploadAsset = Required<Omit<Storage, 'token' | 'encoding' | 'description'>> &\n Pick<Storage, 'token' | 'encoding' | 'description'>;\n\nexport const uploadAsset = async ({\n asset: {data, filename, collection, headers, token, fullPath, encoding, description},\n actor,\n init_asset_upload\n}: {\n asset: UploadAsset;\n actor: SatelliteActor | ConsoleActor;\n init_asset_upload: (\n initAssetKey: SatelliteInitAssetKey | ConsoleInitAssetKey\n ) => Promise<SatelliteInitUploadResult | ConsoleInitUploadResult>;\n}): Promise<void> => {\n const {batch_id: batchId} = await init_asset_upload({\n collection,\n full_path: fullPath,\n name: filename,\n token: toNullable<string>(token),\n encoding_type: toNullable<ENCODING_TYPE>(encoding),\n description: toNullable(description)\n });\n\n // https://forum.dfinity.org/t/optimal-upload-chunk-size/20444/23?u=peterparker\n const chunkSize = 1900000;\n\n const uploadChunks: UploadChunkParams[] = [];\n\n // Prevent transforming chunk to arrayBuffer error: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.\n const clone: Blob = isBrowser() ? new Blob([await data.arrayBuffer()]) : data;\n\n // Split data into chunks\n let orderId = 0n;\n for (let start = 0; start < clone.size; start += chunkSize) {\n const chunk: Blob = clone.slice(start, start + chunkSize);\n\n uploadChunks.push({\n batchId,\n chunk,\n actor,\n orderId\n });\n\n orderId++;\n }\n\n // Upload chunks to the IC in batch - i.e. 12 chunks uploaded at a time.\n let chunkIds: UploadChunkResult[] = [];\n for await (const results of batchUploadChunks({uploadChunks})) {\n chunkIds = [...chunkIds, ...results];\n }\n\n const contentType: [[string, string]] | undefined =\n headers.find(([type, _]) => type.toLowerCase() === 'content-type') === undefined &&\n data.type !== undefined &&\n data.type !== ''\n ? [['Content-Type', data.type]]\n : undefined;\n\n await actor.commit_asset_upload({\n batch_id: batchId,\n chunk_ids: chunkIds.map(({chunk_id}: UploadChunkResult) => chunk_id),\n headers: [...headers, ...(contentType ? contentType : [])]\n });\n};\n\nasync function* batchUploadChunks({\n uploadChunks,\n limit = 12\n}: {\n uploadChunks: UploadChunkParams[];\n limit?: number;\n}): AsyncGenerator<UploadChunkResult[], void> {\n for (let i = 0; i < uploadChunks.length; i = i + limit) {\n const batch = uploadChunks.slice(i, i + limit);\n const result = await Promise.all(batch.map((params) => uploadChunk(params)));\n yield result;\n }\n}\n\ntype UploadChunkResult = {chunk_id: bigint};\n\ntype UploadChunkParams = {\n batchId: bigint;\n chunk: Blob;\n actor: SatelliteActor | ConsoleActor;\n orderId: bigint;\n};\n\nconst uploadChunk = async ({\n batchId,\n chunk,\n actor,\n orderId\n}: UploadChunkParams): Promise<UploadChunkResult> =>\n actor.upload_asset_chunk({\n batch_id: batchId,\n content: new Uint8Array(await chunk.arrayBuffer()),\n order_id: toNullable(orderId)\n });\n"],
|
|
5
|
-
"mappings": ";;ACAA,OAAQ,aAAAA,MAAgB,
|
|
4
|
+
"sourcesContent": ["/**\n * Creates a debounced function that delays invoking the provided function until after the specified timeout.\n * @param {Function} func - The function to debounce.\n * @param {number} [timeout=300] - The number of milliseconds to delay. Defaults to 300ms if not specified or invalid.\n * @returns {Function} A debounced function.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types, local-rules/prefer-object-params\nexport const debounce = (func: Function, timeout?: number): Function => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n return (...args: unknown[]) => {\n const next = () => func(...args);\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(next, timeout !== undefined && timeout > 0 ? timeout : 300);\n };\n};\n", "import {Principal} from '@dfinity/principal';\nimport {nonNullish} from './null.utils';\n\nconst JSON_KEY_BIGINT = '__bigint__';\nconst JSON_KEY_PRINCIPAL = '__principal__';\nconst JSON_KEY_UINT8ARRAY = '__uint8array__';\n\n/**\n * A function that alters the behavior of the stringification process for BigInt, Principal, and Uint8Array.\n * @param {string} _key - The key of the value being stringified.\n * @param {unknown} value - The value being stringified.\n * @returns {unknown} The altered value for stringification.\n */\n// eslint-disable-next-line local-rules/prefer-object-params\nexport const jsonReplacer = (_key: string, value: unknown): unknown => {\n if (typeof value === 'bigint') {\n return {[JSON_KEY_BIGINT]: `${value}`};\n }\n\n if (nonNullish(value) && value instanceof Principal) {\n return {[JSON_KEY_PRINCIPAL]: value.toText()};\n }\n\n if (nonNullish(value) && value instanceof Uint8Array) {\n return {[JSON_KEY_UINT8ARRAY]: Array.from(value)};\n }\n\n return value;\n};\n\n/**\n * A parser that interprets revived BigInt, Principal, and Uint8Array when constructing JavaScript values or objects.\n * @param {string} _key - The key of the value being parsed.\n * @param {unknown} value - The value being parsed.\n * @returns {unknown} The parsed value.\n */\n// eslint-disable-next-line local-rules/prefer-object-params\nexport const jsonReviver = (_key: string, value: unknown): unknown => {\n const mapValue = <T>(key: string): T => (value as Record<string, T>)[key];\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_BIGINT in value) {\n return BigInt(mapValue(JSON_KEY_BIGINT));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_PRINCIPAL in value) {\n return Principal.fromText(mapValue(JSON_KEY_PRINCIPAL));\n }\n\n if (nonNullish(value) && typeof value === 'object' && JSON_KEY_UINT8ARRAY in value) {\n return Uint8Array.from(mapValue(JSON_KEY_UINT8ARRAY));\n }\n\n return value;\n};\n", "/**\n * Checks if the provided argument is null or undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is null or undefined, false otherwise.\n */\n// eslint-disable-next-line local-rules/use-option-type-wrapper\nexport const isNullish = <T>(argument: T | undefined | null): argument is undefined | null =>\n argument === null || argument === undefined;\n\n/**\n * Checks if the provided argument is neither null nor undefined.\n * @template T\n * @param {T | undefined | null} argument - The argument to check.\n * @returns {boolean} True if the argument is neither null nor undefined, false otherwise.\n */\n// eslint-disable-next-line local-rules/use-option-type-wrapper\nexport const nonNullish = <T>(argument: T | undefined | null): argument is NonNullable<T> =>\n !isNullish(argument);\n\n/**\n * Represents an error thrown when a value is null or undefined.\n * @class\n * @extends {Error}\n */\nexport class NullishError extends Error {}\n\n/**\n * Asserts that a value is neither null nor undefined.\n * @template T\n * @param {T} value - The value to check.\n * @param {string} [message] - The optional error message to use if the assertion fails.\n * @throws {NullishError} If the value is null or undefined.\n * @returns {asserts value is NonNullable<T>} Asserts that the value is neither null nor undefined.\n */\nexport const assertNonNullish: <T>(\n value: T,\n message?: string\n // eslint-disable-next-line local-rules/prefer-object-params\n) => asserts value is NonNullable<T> = <T>(value: T, message?: string): void => {\n if (isNullish(value)) {\n throw new NullishError(message);\n }\n};\n", "import {jsonReplacer, jsonReviver} from './json.utils';\nimport {nonNullish} from './null.utils';\n\n/**\n * Converts a value to a nullable array.\n * @template T\n * @param {T} [value] - The value to convert.\n * @returns {([] | [T])} A nullable array containing the value if non-nullish, or an empty array if nullish.\n */\nexport const toNullable = <T>(value?: T): [] | [T] => (nonNullish(value) ? [value] : []);\n\n/**\n * Extracts a value from a nullable array.\n * @template T\n * @param {([] | [T])} value - The nullable array.\n * @returns {(T | undefined)} The value if present, or undefined if the array is empty.\n */\nexport const fromNullable = <T>(value: [] | [T]): T | undefined => value?.[0];\n\n/**\n * Converts data to a Uint8Array for transmission or storage.\n * @template T\n * @param {T} data - The data to convert.\n * @returns {Promise<Uint8Array>} A promise that resolves to a Uint8Array representation of the data.\n */\nexport const toArray = async <T>(data: T): Promise<Uint8Array> => {\n const blob: Blob = new Blob([JSON.stringify(data, jsonReplacer)], {\n type: 'application/json; charset=utf-8'\n });\n return new Uint8Array(await blob.arrayBuffer());\n};\n\n/**\n * Converts a Uint8Array or number array back to the original data type.\n * @template T\n * @param {(Uint8Array | number[])} data - The array to convert.\n * @returns {Promise<T>} A promise that resolves to the original data.\n */\nexport const fromArray = async <T>(data: Uint8Array | number[]): Promise<T> => {\n const blob: Blob = new Blob([data instanceof Uint8Array ? data : new Uint8Array(data)], {\n type: 'application/json; charset=utf-8'\n });\n return JSON.parse(await blob.text(), jsonReviver);\n};\n", "/**\n * Checks if the current environment is a browser.\n * @returns {boolean} True if the current environment is a browser, false otherwise.\n */\nexport const isBrowser = (): boolean => typeof window !== `undefined`;\n", "import {isBrowser, toNullable} from '@junobuild/utils';\nimport type {\n _SERVICE as ConsoleActor,\n InitAssetKey as ConsoleInitAssetKey,\n InitUploadResult as ConsoleInitUploadResult\n} from '../../declarations/console/console.did';\nimport type {\n _SERVICE as SatelliteActor,\n InitAssetKey as SatelliteInitAssetKey,\n InitUploadResult as SatelliteInitUploadResult\n} from '../../declarations/satellite/satellite.did';\nimport type {ENCODING_TYPE, Storage} from '../types/storage.types';\n\nexport type UploadAsset = Required<Omit<Storage, 'token' | 'encoding' | 'description'>> &\n Pick<Storage, 'token' | 'encoding' | 'description'>;\n\nexport const uploadAsset = async ({\n asset: {data, filename, collection, headers, token, fullPath, encoding, description},\n actor,\n init_asset_upload\n}: {\n asset: UploadAsset;\n actor: SatelliteActor | ConsoleActor;\n init_asset_upload: (\n initAssetKey: SatelliteInitAssetKey | ConsoleInitAssetKey\n ) => Promise<SatelliteInitUploadResult | ConsoleInitUploadResult>;\n}): Promise<void> => {\n const {batch_id: batchId} = await init_asset_upload({\n collection,\n full_path: fullPath,\n name: filename,\n token: toNullable<string>(token),\n encoding_type: toNullable<ENCODING_TYPE>(encoding),\n description: toNullable(description)\n });\n\n // https://forum.dfinity.org/t/optimal-upload-chunk-size/20444/23?u=peterparker\n const chunkSize = 1900000;\n\n const uploadChunks: UploadChunkParams[] = [];\n\n // Prevent transforming chunk to arrayBuffer error: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.\n const clone: Blob = isBrowser() ? new Blob([await data.arrayBuffer()]) : data;\n\n // Split data into chunks\n let orderId = 0n;\n for (let start = 0; start < clone.size; start += chunkSize) {\n const chunk: Blob = clone.slice(start, start + chunkSize);\n\n uploadChunks.push({\n batchId,\n chunk,\n actor,\n orderId\n });\n\n orderId++;\n }\n\n // Upload chunks to the IC in batch - i.e. 12 chunks uploaded at a time.\n let chunkIds: UploadChunkResult[] = [];\n for await (const results of batchUploadChunks({uploadChunks})) {\n chunkIds = [...chunkIds, ...results];\n }\n\n const contentType: [[string, string]] | undefined =\n headers.find(([type, _]) => type.toLowerCase() === 'content-type') === undefined &&\n data.type !== undefined &&\n data.type !== ''\n ? [['Content-Type', data.type]]\n : undefined;\n\n await actor.commit_asset_upload({\n batch_id: batchId,\n chunk_ids: chunkIds.map(({chunk_id}: UploadChunkResult) => chunk_id),\n headers: [...headers, ...(contentType ? contentType : [])]\n });\n};\n\nasync function* batchUploadChunks({\n uploadChunks,\n limit = 12\n}: {\n uploadChunks: UploadChunkParams[];\n limit?: number;\n}): AsyncGenerator<UploadChunkResult[], void> {\n for (let i = 0; i < uploadChunks.length; i = i + limit) {\n const batch = uploadChunks.slice(i, i + limit);\n const result = await Promise.all(batch.map((params) => uploadChunk(params)));\n yield result;\n }\n}\n\ninterface UploadChunkResult {\n chunk_id: bigint;\n}\n\ninterface UploadChunkParams {\n batchId: bigint;\n chunk: Blob;\n actor: SatelliteActor | ConsoleActor;\n orderId: bigint;\n}\n\nconst uploadChunk = async ({\n batchId,\n chunk,\n actor,\n orderId\n}: UploadChunkParams): Promise<UploadChunkResult> =>\n actor.upload_asset_chunk({\n batch_id: batchId,\n content: new Uint8Array(await chunk.arrayBuffer()),\n order_id: toNullable(orderId)\n });\n"],
|
|
5
|
+
"mappings": ";;ACAA,OAAQ,aAAAA,MAAgB,qBCOjB,IAAMC,EAAgBC,GAC3BA,GAAa,KASFC,EAAiBD,GAC5B,CAACD,EAAUC,CAAQ,ECTd,IAAME,EAAiBC,GAAyBC,EAAWD,CAAK,EAAI,CAACA,CAAK,EAAI,CAAC,ECL/E,IAAME,EAAY,IAAe,OAAO,OAAW,ICYnD,IAAMC,EAAc,MAAO,CAChC,MAAO,CAAC,KAAAC,EAAM,SAAAC,EAAU,WAAAC,EAAY,QAAAC,EAAS,MAAAC,EAAO,SAAAC,EAAU,SAAAC,EAAU,YAAAC,CAAW,EACnF,MAAAC,EACA,kBAAAC,CACF,IAMqB,CACnB,GAAM,CAAC,SAAUC,CAAO,EAAI,MAAMD,EAAkB,CAClD,WAAAP,EACA,UAAWG,EACX,KAAMJ,EACN,MAAOU,EAAmBP,CAAK,EAC/B,cAAeO,EAA0BL,CAAQ,EACjD,YAAaK,EAAWJ,CAAW,CACrC,CAAC,EAGKK,EAAY,KAEZC,EAAoC,CAAC,EAGrCC,EAAcC,EAAU,EAAI,IAAI,KAAK,CAAC,MAAMf,EAAK,YAAY,CAAC,CAAC,EAAIA,EAGrEgB,EAAU,GACd,QAASC,EAAQ,EAAGA,EAAQH,EAAM,KAAMG,GAASL,EAAW,CAC1D,IAAMM,EAAcJ,EAAM,MAAMG,EAAOA,EAAQL,CAAS,EAExDC,EAAa,KAAK,CAChB,QAAAH,EACA,MAAAQ,EACA,MAAAV,EACA,QAAAQ,CACF,CAAC,EAEDA,GACF,CAGA,IAAIG,EAAgC,CAAC,EACrC,cAAiBC,KAAWC,EAAkB,CAAC,aAAAR,CAAY,CAAC,EAC1DM,EAAW,CAAC,GAAGA,EAAU,GAAGC,CAAO,EAGrC,IAAME,EACJnB,EAAQ,KAAK,CAAC,CAACoB,EAAMC,CAAC,IAAMD,EAAK,YAAY,IAAM,cAAc,IAAM,QACvEvB,EAAK,OAAS,QACdA,EAAK,OAAS,GACV,CAAC,CAAC,eAAgBA,EAAK,IAAI,CAAC,EAC5B,OAEN,MAAMQ,EAAM,oBAAoB,CAC9B,SAAUE,EACV,UAAWS,EAAS,IAAI,CAAC,CAAC,SAAAM,CAAQ,IAAyBA,CAAQ,EACnE,QAAS,CAAC,GAAGtB,EAAS,GAAImB,GAA4B,CAAC,CAAE,CAC3D,CAAC,CACH,EAEA,eAAgBD,EAAkB,CAChC,aAAAR,EACA,MAAAa,EAAQ,EACV,EAG8C,CAC5C,QAASC,EAAI,EAAGA,EAAId,EAAa,OAAQc,EAAIA,EAAID,EAAO,CACtD,IAAME,EAAQf,EAAa,MAAMc,EAAGA,EAAID,CAAK,EAE7C,MADe,MAAM,QAAQ,IAAIE,EAAM,IAAKC,GAAWC,EAAYD,CAAM,CAAC,CAAC,CAE7E,CACF,CAaA,IAAMC,EAAc,MAAO,CACzB,QAAApB,EACA,MAAAQ,EACA,MAAAV,EACA,QAAAQ,CACF,IACER,EAAM,mBAAmB,CACvB,SAAUE,EACV,QAAS,IAAI,WAAW,MAAMQ,EAAM,YAAY,CAAC,EACjD,SAAUP,EAAWK,CAAO,CAC9B,CAAC",
|
|
6
6
|
"names": ["Principal", "isNullish", "argument", "nonNullish", "toNullable", "value", "nonNullish", "isBrowser", "uploadAsset", "data", "filename", "collection", "headers", "token", "fullPath", "encoding", "description", "actor", "init_asset_upload", "batchId", "g", "chunkSize", "uploadChunks", "clone", "h", "orderId", "start", "chunk", "chunkIds", "results", "batchUploadChunks", "contentType", "type", "_", "chunk_id", "limit", "i", "batch", "params", "uploadChunk"]
|
|
7
7
|
}
|