@kokimoki/app 2.1.0 → 3.0.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.
- package/README.md +72 -0
- package/dist/core/kokimoki-client.d.ts +75 -15
- package/dist/core/kokimoki-client.js +137 -22
- package/dist/index.d.ts +6 -1
- package/dist/index.js +4 -0
- package/dist/kokimoki.min.d.ts +322 -2
- package/dist/kokimoki.min.js +1884 -72
- package/dist/kokimoki.min.js.map +1 -1
- package/dist/llms.txt +6 -0
- package/dist/protocol/ws-message/reader.d.ts +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/kokimoki-ai.d.ts +185 -122
- package/dist/services/kokimoki-ai.js +201 -109
- package/dist/services/kokimoki-i18n.d.ts +259 -0
- package/dist/services/kokimoki-i18n.js +325 -0
- package/dist/stores/kokimoki-local-store.d.ts +1 -1
- package/dist/types/common.d.ts +9 -0
- package/dist/types/env.d.ts +36 -0
- package/dist/types/env.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/kokimoki-client.d.ts +31 -0
- package/dist/utils/kokimoki-client.js +38 -0
- package/dist/utils/kokimoki-dev.d.ts +30 -0
- package/dist/utils/kokimoki-dev.js +75 -0
- package/dist/utils/kokimoki-env.d.ts +20 -0
- package/dist/utils/kokimoki-env.js +30 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/kokimoki-ai.instructions.md +316 -0
- package/docs/kokimoki-dynamic-stores.instructions.md +439 -0
- package/docs/kokimoki-i18n.instructions.md +285 -0
- package/docs/kokimoki-leaderboard.instructions.md +189 -0
- package/docs/kokimoki-sdk.instructions.md +221 -0
- package/docs/kokimoki-storage.instructions.md +162 -0
- package/llms.txt +43 -0
- package/package.json +9 -13
package/dist/kokimoki.min.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import HttpBackend from 'i18next-http-backend';
|
|
1
3
|
import require$$1 from 'path';
|
|
2
4
|
import require$$2 from 'fs';
|
|
3
5
|
import { useMemo, useRef, useSyncExternalStore, useCallback, useLayoutEffect, useEffect, useDebugValue } from 'react';
|
|
@@ -493,6 +495,12 @@ var EventEmitter$1 = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);
|
|
|
493
495
|
* @module map
|
|
494
496
|
*/
|
|
495
497
|
|
|
498
|
+
/**
|
|
499
|
+
* @template K
|
|
500
|
+
* @template V
|
|
501
|
+
* @typedef {Map<K,V>} GlobalMap
|
|
502
|
+
*/
|
|
503
|
+
|
|
496
504
|
/**
|
|
497
505
|
* Creates a new Map instance.
|
|
498
506
|
*
|
|
@@ -628,6 +636,58 @@ const appendTo = (dest, src) => {
|
|
|
628
636
|
*/
|
|
629
637
|
const from = Array.from;
|
|
630
638
|
|
|
639
|
+
/**
|
|
640
|
+
* True iff condition holds on every element in the Array.
|
|
641
|
+
*
|
|
642
|
+
* @function
|
|
643
|
+
* @template {ArrayLike<any>} ARR
|
|
644
|
+
*
|
|
645
|
+
* @param {ARR} arr
|
|
646
|
+
* @param {ARR extends ArrayLike<infer S> ? ((value:S, index:number, arr:ARR) => boolean) : any} f
|
|
647
|
+
* @return {boolean}
|
|
648
|
+
*/
|
|
649
|
+
const every$1 = (arr, f) => {
|
|
650
|
+
for (let i = 0; i < arr.length; i++) {
|
|
651
|
+
if (!f(arr[i], i, arr)) {
|
|
652
|
+
return false
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return true
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* True iff condition holds on some element in the Array.
|
|
660
|
+
*
|
|
661
|
+
* @function
|
|
662
|
+
* @template {ArrayLike<any>} ARR
|
|
663
|
+
*
|
|
664
|
+
* @param {ARR} arr
|
|
665
|
+
* @param {ARR extends ArrayLike<infer S> ? ((value:S, index:number, arr:ARR) => boolean) : never} f
|
|
666
|
+
* @return {boolean}
|
|
667
|
+
*/
|
|
668
|
+
const some = (arr, f) => {
|
|
669
|
+
for (let i = 0; i < arr.length; i++) {
|
|
670
|
+
if (f(arr[i], i, arr)) {
|
|
671
|
+
return true
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return false
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* @template T
|
|
679
|
+
* @param {number} len
|
|
680
|
+
* @param {function(number, Array<T>):T} f
|
|
681
|
+
* @return {Array<T>}
|
|
682
|
+
*/
|
|
683
|
+
const unfold = (len, f) => {
|
|
684
|
+
const array = new Array(len);
|
|
685
|
+
for (let i = 0; i < len; i++) {
|
|
686
|
+
array[i] = f(i, array);
|
|
687
|
+
}
|
|
688
|
+
return array
|
|
689
|
+
};
|
|
690
|
+
|
|
631
691
|
const isArray$1 = Array.isArray;
|
|
632
692
|
|
|
633
693
|
/**
|
|
@@ -743,8 +803,10 @@ const min$2 = (a, b) => a < b ? a : b;
|
|
|
743
803
|
const max$3 = (a, b) => a > b ? a : b;
|
|
744
804
|
|
|
745
805
|
/**
|
|
806
|
+
* Check whether n is negative, while considering the -0 edge case. While `-0 < 0` is false, this
|
|
807
|
+
* function returns true for -0,-1,,.. and returns false for 0,1,2,...
|
|
746
808
|
* @param {number} n
|
|
747
|
-
* @return {boolean} Wether n is negative. This function also
|
|
809
|
+
* @return {boolean} Wether n is negative. This function also distinguishes between -0 and +0
|
|
748
810
|
*/
|
|
749
811
|
const isNegativeZero = n => n !== 0 ? n < 0 : 1 / n < 0;
|
|
750
812
|
|
|
@@ -784,10 +846,19 @@ const BITS31 = 0x7FFFFFFF;
|
|
|
784
846
|
|
|
785
847
|
|
|
786
848
|
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
|
|
849
|
+
const MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER;
|
|
787
850
|
|
|
788
851
|
/* c8 ignore next */
|
|
789
852
|
const isInteger = Number.isInteger || (num => typeof num === 'number' && isFinite(num) && floor$2(num) === num);
|
|
790
853
|
|
|
854
|
+
/**
|
|
855
|
+
* Utility module to work with strings.
|
|
856
|
+
*
|
|
857
|
+
* @module string
|
|
858
|
+
*/
|
|
859
|
+
|
|
860
|
+
const fromCharCode = String.fromCharCode;
|
|
861
|
+
|
|
791
862
|
/**
|
|
792
863
|
* @param {string} s
|
|
793
864
|
* @return {string}
|
|
@@ -813,7 +884,7 @@ const fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, m
|
|
|
813
884
|
|
|
814
885
|
/**
|
|
815
886
|
* @param {string} str
|
|
816
|
-
* @return {Uint8Array}
|
|
887
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
817
888
|
*/
|
|
818
889
|
const _encodeUtf8Polyfill = str => {
|
|
819
890
|
const encodedString = unescape(encodeURIComponent(str));
|
|
@@ -830,7 +901,7 @@ const utf8TextEncoder = /** @type {TextEncoder} */ (typeof TextEncoder !== 'unde
|
|
|
830
901
|
|
|
831
902
|
/**
|
|
832
903
|
* @param {string} str
|
|
833
|
-
* @return {Uint8Array}
|
|
904
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
834
905
|
*/
|
|
835
906
|
const _encodeUtf8Native = str => utf8TextEncoder.encode(str);
|
|
836
907
|
|
|
@@ -855,6 +926,12 @@ if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) {
|
|
|
855
926
|
utf8TextDecoder = null;
|
|
856
927
|
}
|
|
857
928
|
|
|
929
|
+
/**
|
|
930
|
+
* @param {string} source
|
|
931
|
+
* @param {number} n
|
|
932
|
+
*/
|
|
933
|
+
const repeat = (source, n) => unfold(n, () => source).join('');
|
|
934
|
+
|
|
858
935
|
/**
|
|
859
936
|
* Efficient schema-less binary encoding with support for variable length encoding.
|
|
860
937
|
*
|
|
@@ -924,7 +1001,7 @@ const length = encoder => {
|
|
|
924
1001
|
*
|
|
925
1002
|
* @function
|
|
926
1003
|
* @param {Encoder} encoder
|
|
927
|
-
* @return {Uint8Array} The created ArrayBuffer.
|
|
1004
|
+
* @return {Uint8Array<ArrayBuffer>} The created ArrayBuffer.
|
|
928
1005
|
*/
|
|
929
1006
|
const toUint8Array = encoder => {
|
|
930
1007
|
const uint8arr = new Uint8Array(length(encoder));
|
|
@@ -1165,6 +1242,14 @@ const isFloat32 = num => {
|
|
|
1165
1242
|
return floatTestBed.getFloat32(0) === num
|
|
1166
1243
|
};
|
|
1167
1244
|
|
|
1245
|
+
/**
|
|
1246
|
+
* @typedef {Array<AnyEncodable>} AnyEncodableArray
|
|
1247
|
+
*/
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* @typedef {undefined|null|number|bigint|boolean|string|{[k:string]:AnyEncodable}|AnyEncodableArray|Uint8Array} AnyEncodable
|
|
1251
|
+
*/
|
|
1252
|
+
|
|
1168
1253
|
/**
|
|
1169
1254
|
* Encode data with efficient binary format.
|
|
1170
1255
|
*
|
|
@@ -1200,7 +1285,7 @@ const isFloat32 = num => {
|
|
|
1200
1285
|
* lib0/encoding.js
|
|
1201
1286
|
*
|
|
1202
1287
|
* @param {Encoder} encoder
|
|
1203
|
-
* @param {
|
|
1288
|
+
* @param {AnyEncodable} data
|
|
1204
1289
|
*/
|
|
1205
1290
|
const writeAny = (encoder, data) => {
|
|
1206
1291
|
switch (typeof data) {
|
|
@@ -1554,16 +1639,17 @@ const errorIntegerOutOfRange = create$3('Integer out of Range');
|
|
|
1554
1639
|
|
|
1555
1640
|
/**
|
|
1556
1641
|
* A Decoder handles the decoding of an Uint8Array.
|
|
1642
|
+
* @template {ArrayBufferLike} [Buf=ArrayBufferLike]
|
|
1557
1643
|
*/
|
|
1558
1644
|
class Decoder {
|
|
1559
1645
|
/**
|
|
1560
|
-
* @param {Uint8Array} uint8Array Binary data to decode
|
|
1646
|
+
* @param {Uint8Array<Buf>} uint8Array Binary data to decode
|
|
1561
1647
|
*/
|
|
1562
1648
|
constructor (uint8Array) {
|
|
1563
1649
|
/**
|
|
1564
1650
|
* Decoding target.
|
|
1565
1651
|
*
|
|
1566
|
-
* @type {Uint8Array}
|
|
1652
|
+
* @type {Uint8Array<Buf>}
|
|
1567
1653
|
*/
|
|
1568
1654
|
this.arr = uint8Array;
|
|
1569
1655
|
/**
|
|
@@ -1577,8 +1663,9 @@ class Decoder {
|
|
|
1577
1663
|
|
|
1578
1664
|
/**
|
|
1579
1665
|
* @function
|
|
1580
|
-
* @
|
|
1581
|
-
* @
|
|
1666
|
+
* @template {ArrayBufferLike} Buf
|
|
1667
|
+
* @param {Uint8Array<Buf>} uint8Array
|
|
1668
|
+
* @return {Decoder<Buf>}
|
|
1582
1669
|
*/
|
|
1583
1670
|
const createDecoder = uint8Array => new Decoder(uint8Array);
|
|
1584
1671
|
|
|
@@ -1596,9 +1683,10 @@ const hasContent = decoder => decoder.pos !== decoder.arr.length;
|
|
|
1596
1683
|
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
1597
1684
|
*
|
|
1598
1685
|
* @function
|
|
1599
|
-
* @
|
|
1686
|
+
* @template {ArrayBufferLike} Buf
|
|
1687
|
+
* @param {Decoder<Buf>} decoder The decoder instance
|
|
1600
1688
|
* @param {number} len The length of bytes to read
|
|
1601
|
-
* @return {Uint8Array}
|
|
1689
|
+
* @return {Uint8Array<Buf>}
|
|
1602
1690
|
*/
|
|
1603
1691
|
const readUint8Array = (decoder, len) => {
|
|
1604
1692
|
const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
|
|
@@ -1613,8 +1701,9 @@ const readUint8Array = (decoder, len) => {
|
|
|
1613
1701
|
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
1614
1702
|
*
|
|
1615
1703
|
* @function
|
|
1616
|
-
* @
|
|
1617
|
-
* @
|
|
1704
|
+
* @template {ArrayBufferLike} Buf
|
|
1705
|
+
* @param {Decoder<Buf>} decoder
|
|
1706
|
+
* @return {Uint8Array<Buf>}
|
|
1618
1707
|
*/
|
|
1619
1708
|
const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint(decoder));
|
|
1620
1709
|
|
|
@@ -2070,12 +2159,38 @@ try {
|
|
|
2070
2159
|
/* c8 ignore next */
|
|
2071
2160
|
const varStorage = _localStorage;
|
|
2072
2161
|
|
|
2162
|
+
const EqualityTraitSymbol = Symbol('Equality');
|
|
2163
|
+
|
|
2073
2164
|
/**
|
|
2074
|
-
*
|
|
2165
|
+
* @typedef {{ [EqualityTraitSymbol]:(other:EqualityTrait)=>boolean }} EqualityTrait
|
|
2166
|
+
*/
|
|
2167
|
+
|
|
2168
|
+
/**
|
|
2169
|
+
*
|
|
2170
|
+
* Utility function to compare any two objects.
|
|
2075
2171
|
*
|
|
2076
|
-
*
|
|
2172
|
+
* Note that it is expected that the first parameter is more specific than the latter one.
|
|
2173
|
+
*
|
|
2174
|
+
* @example js
|
|
2175
|
+
* class X { [traits.EqualityTraitSymbol] (other) { return other === this } }
|
|
2176
|
+
* class X2 { [traits.EqualityTraitSymbol] (other) { return other === this }, x2 () { return 2 } }
|
|
2177
|
+
* // this is fine
|
|
2178
|
+
* traits.equals(new X2(), new X())
|
|
2179
|
+
* // this is not, because the left type is less specific than the right one
|
|
2180
|
+
* traits.equals(new X(), new X2())
|
|
2181
|
+
*
|
|
2182
|
+
* @template {EqualityTrait} T
|
|
2183
|
+
* @param {NoInfer<T>} a
|
|
2184
|
+
* @param {T} b
|
|
2185
|
+
* @return {boolean}
|
|
2077
2186
|
*/
|
|
2187
|
+
const equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false;
|
|
2078
2188
|
|
|
2189
|
+
/**
|
|
2190
|
+
* @param {any} o
|
|
2191
|
+
* @return {o is { [k:string]:any }}
|
|
2192
|
+
*/
|
|
2193
|
+
const isObject$2 = o => typeof o === 'object';
|
|
2079
2194
|
|
|
2080
2195
|
/**
|
|
2081
2196
|
* Object.assign
|
|
@@ -2144,7 +2259,7 @@ const hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
|
|
2144
2259
|
* @param {Object<string,any>} b
|
|
2145
2260
|
* @return {boolean}
|
|
2146
2261
|
*/
|
|
2147
|
-
const equalFlat = (a, b) => a === b || (size(a) === size(b) && every(a, (val, key) => (val !== undefined || hasProperty(b, key)) && b[key]
|
|
2262
|
+
const equalFlat = (a, b) => a === b || (size(a) === size(b) && every(a, (val, key) => (val !== undefined || hasProperty(b, key)) && equals(b[key], val)));
|
|
2148
2263
|
|
|
2149
2264
|
/**
|
|
2150
2265
|
* Make an object immutable. This hurts performance and is usually not needed if you perform good
|
|
@@ -2203,6 +2318,88 @@ const callAll = (fs, args, i = 0) => {
|
|
|
2203
2318
|
*/
|
|
2204
2319
|
const id = a => a;
|
|
2205
2320
|
|
|
2321
|
+
/* c8 ignore start */
|
|
2322
|
+
|
|
2323
|
+
/**
|
|
2324
|
+
* @param {any} a
|
|
2325
|
+
* @param {any} b
|
|
2326
|
+
* @return {boolean}
|
|
2327
|
+
*/
|
|
2328
|
+
const equalityDeep = (a, b) => {
|
|
2329
|
+
if (a === b) {
|
|
2330
|
+
return true
|
|
2331
|
+
}
|
|
2332
|
+
if (a == null || b == null || (a.constructor !== b.constructor && (a.constructor || Object) !== (b.constructor || Object))) {
|
|
2333
|
+
return false
|
|
2334
|
+
}
|
|
2335
|
+
if (a[EqualityTraitSymbol] != null) {
|
|
2336
|
+
return a[EqualityTraitSymbol](b)
|
|
2337
|
+
}
|
|
2338
|
+
switch (a.constructor) {
|
|
2339
|
+
case ArrayBuffer:
|
|
2340
|
+
a = new Uint8Array(a);
|
|
2341
|
+
b = new Uint8Array(b);
|
|
2342
|
+
// eslint-disable-next-line no-fallthrough
|
|
2343
|
+
case Uint8Array: {
|
|
2344
|
+
if (a.byteLength !== b.byteLength) {
|
|
2345
|
+
return false
|
|
2346
|
+
}
|
|
2347
|
+
for (let i = 0; i < a.length; i++) {
|
|
2348
|
+
if (a[i] !== b[i]) {
|
|
2349
|
+
return false
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
break
|
|
2353
|
+
}
|
|
2354
|
+
case Set: {
|
|
2355
|
+
if (a.size !== b.size) {
|
|
2356
|
+
return false
|
|
2357
|
+
}
|
|
2358
|
+
for (const value of a) {
|
|
2359
|
+
if (!b.has(value)) {
|
|
2360
|
+
return false
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
break
|
|
2364
|
+
}
|
|
2365
|
+
case Map: {
|
|
2366
|
+
if (a.size !== b.size) {
|
|
2367
|
+
return false
|
|
2368
|
+
}
|
|
2369
|
+
for (const key of a.keys()) {
|
|
2370
|
+
if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) {
|
|
2371
|
+
return false
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
break
|
|
2375
|
+
}
|
|
2376
|
+
case undefined:
|
|
2377
|
+
case Object:
|
|
2378
|
+
if (size(a) !== size(b)) {
|
|
2379
|
+
return false
|
|
2380
|
+
}
|
|
2381
|
+
for (const key in a) {
|
|
2382
|
+
if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) {
|
|
2383
|
+
return false
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
break
|
|
2387
|
+
case Array:
|
|
2388
|
+
if (a.length !== b.length) {
|
|
2389
|
+
return false
|
|
2390
|
+
}
|
|
2391
|
+
for (let i = 0; i < a.length; i++) {
|
|
2392
|
+
if (!equalityDeep(a[i], b[i])) {
|
|
2393
|
+
return false
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
break
|
|
2397
|
+
default:
|
|
2398
|
+
return false
|
|
2399
|
+
}
|
|
2400
|
+
return true
|
|
2401
|
+
};
|
|
2402
|
+
|
|
2206
2403
|
/**
|
|
2207
2404
|
* @template V
|
|
2208
2405
|
* @template {V} OPTS
|
|
@@ -2297,7 +2494,7 @@ const hasConf = (name) =>
|
|
|
2297
2494
|
hasParam('--' + name) || getVariable(name) !== null;
|
|
2298
2495
|
|
|
2299
2496
|
/* c8 ignore next */
|
|
2300
|
-
hasConf('production');
|
|
2497
|
+
const production = hasConf('production');
|
|
2301
2498
|
|
|
2302
2499
|
/* c8 ignore next 2 */
|
|
2303
2500
|
const forceColor = isNode &&
|
|
@@ -2324,67 +2521,1281 @@ const supportsColor = forceColor || (
|
|
|
2324
2521
|
/* c8 ignore stop */
|
|
2325
2522
|
|
|
2326
2523
|
/**
|
|
2327
|
-
* Utility functions to work with buffers (Uint8Array).
|
|
2524
|
+
* Utility functions to work with buffers (Uint8Array).
|
|
2525
|
+
*
|
|
2526
|
+
* @module buffer
|
|
2527
|
+
*/
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
/**
|
|
2531
|
+
* @param {number} len
|
|
2532
|
+
*/
|
|
2533
|
+
const createUint8ArrayFromLen = len => new Uint8Array(len);
|
|
2534
|
+
|
|
2535
|
+
/**
|
|
2536
|
+
* Copy the content of an Uint8Array view to a new ArrayBuffer.
|
|
2537
|
+
*
|
|
2538
|
+
* @param {Uint8Array} uint8Array
|
|
2539
|
+
* @return {Uint8Array}
|
|
2540
|
+
*/
|
|
2541
|
+
const copyUint8Array = uint8Array => {
|
|
2542
|
+
const newBuf = createUint8ArrayFromLen(uint8Array.byteLength);
|
|
2543
|
+
newBuf.set(uint8Array);
|
|
2544
|
+
return newBuf
|
|
2545
|
+
};
|
|
2546
|
+
|
|
2547
|
+
/**
|
|
2548
|
+
* Working with value pairs.
|
|
2549
|
+
*
|
|
2550
|
+
* @module pair
|
|
2551
|
+
*/
|
|
2552
|
+
|
|
2553
|
+
/**
|
|
2554
|
+
* @template L,R
|
|
2555
|
+
*/
|
|
2556
|
+
class Pair {
|
|
2557
|
+
/**
|
|
2558
|
+
* @param {L} left
|
|
2559
|
+
* @param {R} right
|
|
2560
|
+
*/
|
|
2561
|
+
constructor (left, right) {
|
|
2562
|
+
this.left = left;
|
|
2563
|
+
this.right = right;
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
/**
|
|
2568
|
+
* @template L,R
|
|
2569
|
+
* @param {L} left
|
|
2570
|
+
* @param {R} right
|
|
2571
|
+
* @return {Pair<L,R>}
|
|
2572
|
+
*/
|
|
2573
|
+
const create$1 = (left, right) => new Pair(left, right);
|
|
2574
|
+
|
|
2575
|
+
/**
|
|
2576
|
+
* Fast Pseudo Random Number Generators.
|
|
2577
|
+
*
|
|
2578
|
+
* Given a seed a PRNG generates a sequence of numbers that cannot be reasonably predicted.
|
|
2579
|
+
* Two PRNGs must generate the same random sequence of numbers if given the same seed.
|
|
2580
|
+
*
|
|
2581
|
+
* @module prng
|
|
2582
|
+
*/
|
|
2583
|
+
|
|
2584
|
+
|
|
2585
|
+
/**
|
|
2586
|
+
* Generates a single random bool.
|
|
2587
|
+
*
|
|
2588
|
+
* @param {PRNG} gen A random number generator.
|
|
2589
|
+
* @return {Boolean} A random boolean
|
|
2590
|
+
*/
|
|
2591
|
+
const bool = gen => (gen.next() >= 0.5);
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* Generates a random integer with 53 bit resolution.
|
|
2595
|
+
*
|
|
2596
|
+
* @param {PRNG} gen A random number generator.
|
|
2597
|
+
* @param {Number} min The lower bound of the allowed return values (inclusive).
|
|
2598
|
+
* @param {Number} max The upper bound of the allowed return values (inclusive).
|
|
2599
|
+
* @return {Number} A random integer on [min, max]
|
|
2600
|
+
*/
|
|
2601
|
+
const int53 = (gen, min, max) => floor$2(gen.next() * (max + 1 - min) + min);
|
|
2602
|
+
|
|
2603
|
+
/**
|
|
2604
|
+
* Generates a random integer with 32 bit resolution.
|
|
2605
|
+
*
|
|
2606
|
+
* @param {PRNG} gen A random number generator.
|
|
2607
|
+
* @param {Number} min The lower bound of the allowed return values (inclusive).
|
|
2608
|
+
* @param {Number} max The upper bound of the allowed return values (inclusive).
|
|
2609
|
+
* @return {Number} A random integer on [min, max]
|
|
2610
|
+
*/
|
|
2611
|
+
const int32 = (gen, min, max) => floor$2(gen.next() * (max + 1 - min) + min);
|
|
2612
|
+
|
|
2613
|
+
/**
|
|
2614
|
+
* @deprecated
|
|
2615
|
+
* Optimized version of prng.int32. It has the same precision as prng.int32, but should be preferred when
|
|
2616
|
+
* openaring on smaller ranges.
|
|
2617
|
+
*
|
|
2618
|
+
* @param {PRNG} gen A random number generator.
|
|
2619
|
+
* @param {Number} min The lower bound of the allowed return values (inclusive).
|
|
2620
|
+
* @param {Number} max The upper bound of the allowed return values (inclusive). The max inclusive number is `binary.BITS31-1`
|
|
2621
|
+
* @return {Number} A random integer on [min, max]
|
|
2622
|
+
*/
|
|
2623
|
+
const int31 = (gen, min, max) => int32(gen, min, max);
|
|
2624
|
+
|
|
2625
|
+
/**
|
|
2626
|
+
* @param {PRNG} gen
|
|
2627
|
+
* @return {string} A single letter (a-z)
|
|
2628
|
+
*/
|
|
2629
|
+
const letter = gen => fromCharCode(int31(gen, 97, 122));
|
|
2630
|
+
|
|
2631
|
+
/**
|
|
2632
|
+
* @param {PRNG} gen
|
|
2633
|
+
* @param {number} [minLen=0]
|
|
2634
|
+
* @param {number} [maxLen=20]
|
|
2635
|
+
* @return {string} A random word (0-20 characters) without spaces consisting of letters (a-z)
|
|
2636
|
+
*/
|
|
2637
|
+
const word = (gen, minLen = 0, maxLen = 20) => {
|
|
2638
|
+
const len = int31(gen, minLen, maxLen);
|
|
2639
|
+
let str = '';
|
|
2640
|
+
for (let i = 0; i < len; i++) {
|
|
2641
|
+
str += letter(gen);
|
|
2642
|
+
}
|
|
2643
|
+
return str
|
|
2644
|
+
};
|
|
2645
|
+
|
|
2646
|
+
/**
|
|
2647
|
+
* Returns one element of a given array.
|
|
2648
|
+
*
|
|
2649
|
+
* @param {PRNG} gen A random number generator.
|
|
2650
|
+
* @param {Array<T>} array Non empty Array of possible values.
|
|
2651
|
+
* @return {T} One of the values of the supplied Array.
|
|
2652
|
+
* @template T
|
|
2653
|
+
*/
|
|
2654
|
+
const oneOf = (gen, array) => array[int31(gen, 0, array.length - 1)];
|
|
2655
|
+
/* c8 ignore stop */
|
|
2656
|
+
|
|
2657
|
+
/**
|
|
2658
|
+
* @experimental WIP
|
|
2659
|
+
*
|
|
2660
|
+
* Simple & efficient schemas for your data.
|
|
2661
|
+
*/
|
|
2662
|
+
|
|
2663
|
+
|
|
2664
|
+
/**
|
|
2665
|
+
* @typedef {string|number|bigint|boolean|null|undefined|symbol} Primitive
|
|
2666
|
+
*/
|
|
2667
|
+
|
|
2668
|
+
/**
|
|
2669
|
+
* @typedef {{ [k:string|number|symbol]: any }} AnyObject
|
|
2670
|
+
*/
|
|
2671
|
+
|
|
2672
|
+
/**
|
|
2673
|
+
* @template T
|
|
2674
|
+
* @typedef {T extends Schema<infer X> ? X : T} Unwrap
|
|
2675
|
+
*/
|
|
2676
|
+
|
|
2677
|
+
/**
|
|
2678
|
+
* @template T
|
|
2679
|
+
* @typedef {T extends Schema<infer X> ? X : T} TypeOf
|
|
2680
|
+
*/
|
|
2681
|
+
|
|
2682
|
+
/**
|
|
2683
|
+
* @template {readonly unknown[]} T
|
|
2684
|
+
* @typedef {T extends readonly [Schema<infer First>, ...infer Rest] ? [First, ...UnwrapArray<Rest>] : [] } UnwrapArray
|
|
2685
|
+
*/
|
|
2686
|
+
|
|
2687
|
+
/**
|
|
2688
|
+
* @template T
|
|
2689
|
+
* @typedef {T extends Schema<infer S> ? Schema<S> : never} CastToSchema
|
|
2690
|
+
*/
|
|
2691
|
+
|
|
2692
|
+
/**
|
|
2693
|
+
* @template {unknown[]} Arr
|
|
2694
|
+
* @typedef {Arr extends [...unknown[], infer L] ? L : never} TupleLast
|
|
2695
|
+
*/
|
|
2696
|
+
|
|
2697
|
+
/**
|
|
2698
|
+
* @template {unknown[]} Arr
|
|
2699
|
+
* @typedef {Arr extends [...infer Fs, unknown] ? Fs : never} TuplePop
|
|
2700
|
+
*/
|
|
2701
|
+
|
|
2702
|
+
/**
|
|
2703
|
+
* @template {readonly unknown[]} T
|
|
2704
|
+
* @typedef {T extends []
|
|
2705
|
+
* ? {}
|
|
2706
|
+
* : T extends [infer First]
|
|
2707
|
+
* ? First
|
|
2708
|
+
* : T extends [infer First, ...infer Rest]
|
|
2709
|
+
* ? First & Intersect<Rest>
|
|
2710
|
+
* : never
|
|
2711
|
+
* } Intersect
|
|
2712
|
+
*/
|
|
2713
|
+
|
|
2714
|
+
const schemaSymbol = Symbol('0schema');
|
|
2715
|
+
|
|
2716
|
+
class ValidationError {
|
|
2717
|
+
constructor () {
|
|
2718
|
+
/**
|
|
2719
|
+
* Reverse errors
|
|
2720
|
+
* @type {Array<{ path: string?, expected: string, has: string, message: string? }>}
|
|
2721
|
+
*/
|
|
2722
|
+
this._rerrs = [];
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
/**
|
|
2726
|
+
* @param {string?} path
|
|
2727
|
+
* @param {string} expected
|
|
2728
|
+
* @param {string} has
|
|
2729
|
+
* @param {string?} message
|
|
2730
|
+
*/
|
|
2731
|
+
extend (path, expected, has, message = null) {
|
|
2732
|
+
this._rerrs.push({ path, expected, has, message });
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
toString () {
|
|
2736
|
+
const s = [];
|
|
2737
|
+
for (let i = this._rerrs.length - 1; i > 0; i--) {
|
|
2738
|
+
const r = this._rerrs[i];
|
|
2739
|
+
/* c8 ignore next */
|
|
2740
|
+
s.push(repeat(' ', (this._rerrs.length - i) * 2) + `${r.path != null ? `[${r.path}] ` : ''}${r.has} doesn't match ${r.expected}. ${r.message}`);
|
|
2741
|
+
}
|
|
2742
|
+
return s.join('\n')
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
/**
|
|
2747
|
+
* @param {any} a
|
|
2748
|
+
* @param {any} b
|
|
2749
|
+
* @return {boolean}
|
|
2750
|
+
*/
|
|
2751
|
+
const shapeExtends = (a, b) => {
|
|
2752
|
+
if (a === b) return true
|
|
2753
|
+
if (a == null || b == null || a.constructor !== b.constructor) return false
|
|
2754
|
+
if (a[EqualityTraitSymbol]) return equals(a, b) // last resort: check equality (do this before array and obj check which don't implement the equality trait)
|
|
2755
|
+
if (isArray$1(a)) {
|
|
2756
|
+
return every$1(a, aitem =>
|
|
2757
|
+
some(b, bitem => shapeExtends(aitem, bitem))
|
|
2758
|
+
)
|
|
2759
|
+
} else if (isObject$2(a)) {
|
|
2760
|
+
return every(a, (aitem, akey) =>
|
|
2761
|
+
shapeExtends(aitem, b[akey])
|
|
2762
|
+
)
|
|
2763
|
+
}
|
|
2764
|
+
/* c8 ignore next */
|
|
2765
|
+
return false
|
|
2766
|
+
};
|
|
2767
|
+
|
|
2768
|
+
/**
|
|
2769
|
+
* @template T
|
|
2770
|
+
* @implements {equalityTraits.EqualityTrait}
|
|
2771
|
+
*/
|
|
2772
|
+
class Schema {
|
|
2773
|
+
// this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore
|
|
2774
|
+
/**
|
|
2775
|
+
* If true, the more things are added to the shape the more objects this schema will accept (e.g.
|
|
2776
|
+
* union). By default, the more objects are added, the the fewer objects this schema will accept.
|
|
2777
|
+
* @protected
|
|
2778
|
+
*/
|
|
2779
|
+
static _dilutes = false
|
|
2780
|
+
|
|
2781
|
+
/**
|
|
2782
|
+
* @param {Schema<any>} other
|
|
2783
|
+
*/
|
|
2784
|
+
extends (other) {
|
|
2785
|
+
let [a, b] = [/** @type {any} */(this).shape, /** @type {any} */ (other).shape];
|
|
2786
|
+
if (/** @type {typeof Schema<any>} */ (this.constructor)._dilutes) [b, a] = [a, b];
|
|
2787
|
+
return shapeExtends(a, b)
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
/**
|
|
2791
|
+
* Overwrite this when necessary. By default, we only check the `shape` property which every shape
|
|
2792
|
+
* should have.
|
|
2793
|
+
* @param {Schema<any>} other
|
|
2794
|
+
*/
|
|
2795
|
+
equals (other) {
|
|
2796
|
+
// @ts-ignore
|
|
2797
|
+
return this.constructor === other.constructor && equalityDeep(this.shape, other.shape)
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
[schemaSymbol] () { return true }
|
|
2801
|
+
|
|
2802
|
+
/**
|
|
2803
|
+
* @param {object} other
|
|
2804
|
+
*/
|
|
2805
|
+
[EqualityTraitSymbol] (other) {
|
|
2806
|
+
return this.equals(/** @type {any} */ (other))
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
/**
|
|
2810
|
+
* Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of
|
|
2811
|
+
* Schema. Validate will check the structure of the parameter and return true iff the instance
|
|
2812
|
+
* really is an instance of Schema.
|
|
2813
|
+
*
|
|
2814
|
+
* @param {T} o
|
|
2815
|
+
* @return {boolean}
|
|
2816
|
+
*/
|
|
2817
|
+
validate (o) {
|
|
2818
|
+
return this.check(o)
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
/* c8 ignore start */
|
|
2822
|
+
/**
|
|
2823
|
+
* Similar to validate, but this method accepts untyped parameters.
|
|
2824
|
+
*
|
|
2825
|
+
* @param {any} _o
|
|
2826
|
+
* @param {ValidationError} [_err]
|
|
2827
|
+
* @return {_o is T}
|
|
2828
|
+
*/
|
|
2829
|
+
check (_o, _err) {
|
|
2830
|
+
methodUnimplemented();
|
|
2831
|
+
}
|
|
2832
|
+
/* c8 ignore stop */
|
|
2833
|
+
|
|
2834
|
+
/**
|
|
2835
|
+
* @type {Schema<T?>}
|
|
2836
|
+
*/
|
|
2837
|
+
get nullable () {
|
|
2838
|
+
// @ts-ignore
|
|
2839
|
+
return $union(this, $null)
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
/**
|
|
2843
|
+
* @type {$Optional<Schema<T>>}
|
|
2844
|
+
*/
|
|
2845
|
+
get optional () {
|
|
2846
|
+
return new $Optional(/** @type {Schema<T>} */ (this))
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
/**
|
|
2850
|
+
* Cast a variable to a specific type. Returns the casted value, or throws an exception otherwise.
|
|
2851
|
+
* Use this if you know that the type is of a specific type and you just want to convince the type
|
|
2852
|
+
* system.
|
|
2853
|
+
*
|
|
2854
|
+
* **Do not rely on these error messages!**
|
|
2855
|
+
* Performs an assertion check only if not in a production environment.
|
|
2856
|
+
*
|
|
2857
|
+
* @template OO
|
|
2858
|
+
* @param {OO} o
|
|
2859
|
+
* @return {Extract<OO, T> extends never ? T : (OO extends Array<never> ? T : Extract<OO,T>)}
|
|
2860
|
+
*/
|
|
2861
|
+
cast (o) {
|
|
2862
|
+
assert(o, this);
|
|
2863
|
+
return /** @type {any} */ (o)
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
/**
|
|
2867
|
+
* EXPECTO PATRONUM!! 🪄
|
|
2868
|
+
* This function protects against type errors. Though it may not work in the real world.
|
|
2869
|
+
*
|
|
2870
|
+
* "After all this time?"
|
|
2871
|
+
* "Always." - Snape, talking about type safety
|
|
2872
|
+
*
|
|
2873
|
+
* Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed.
|
|
2874
|
+
* Use this if you know that the type is of a specific type and you just want to convince the type
|
|
2875
|
+
* system.
|
|
2876
|
+
*
|
|
2877
|
+
* Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).expect((n) => n + 1)`
|
|
2878
|
+
*
|
|
2879
|
+
* **Do not rely on these error messages!**
|
|
2880
|
+
* Performs an assertion check if not in a production environment.
|
|
2881
|
+
*
|
|
2882
|
+
* @param {T} o
|
|
2883
|
+
* @return {o extends T ? T : never}
|
|
2884
|
+
*/
|
|
2885
|
+
expect (o) {
|
|
2886
|
+
assert(o, this);
|
|
2887
|
+
return o
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
/**
|
|
2892
|
+
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} Constr
|
|
2893
|
+
* @typedef {Constr extends ((...args:any[]) => infer T) ? T : (Constr extends (new (...args:any[]) => any) ? InstanceType<Constr> : never)} Instance
|
|
2894
|
+
*/
|
|
2895
|
+
|
|
2896
|
+
/**
|
|
2897
|
+
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} C
|
|
2898
|
+
* @extends {Schema<Instance<C>>}
|
|
2899
|
+
*/
|
|
2900
|
+
class $ConstructedBy extends Schema {
|
|
2901
|
+
/**
|
|
2902
|
+
* @param {C} c
|
|
2903
|
+
* @param {((o:Instance<C>)=>boolean)|null} check
|
|
2904
|
+
*/
|
|
2905
|
+
constructor (c, check) {
|
|
2906
|
+
super();
|
|
2907
|
+
this.shape = c;
|
|
2908
|
+
this._c = check;
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
/**
|
|
2912
|
+
* @param {any} o
|
|
2913
|
+
* @param {ValidationError} [err]
|
|
2914
|
+
* @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o
|
|
2915
|
+
*/
|
|
2916
|
+
check (o, err = undefined) {
|
|
2917
|
+
const c = o?.constructor === this.shape && (this._c == null || this._c(o));
|
|
2918
|
+
/* c8 ignore next */
|
|
2919
|
+
!c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? 'Constructor match failed' : 'Check failed');
|
|
2920
|
+
return c
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
/**
|
|
2925
|
+
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} C
|
|
2926
|
+
* @param {C} c
|
|
2927
|
+
* @param {((o:Instance<C>) => boolean)|null} check
|
|
2928
|
+
* @return {CastToSchema<$ConstructedBy<C>>}
|
|
2929
|
+
*/
|
|
2930
|
+
const $constructedBy = (c, check = null) => new $ConstructedBy(c, check);
|
|
2931
|
+
$constructedBy($ConstructedBy);
|
|
2932
|
+
|
|
2933
|
+
/**
|
|
2934
|
+
* Check custom properties on any object. You may want to overwrite the generated Schema<any>.
|
|
2935
|
+
*
|
|
2936
|
+
* @extends {Schema<any>}
|
|
2937
|
+
*/
|
|
2938
|
+
class $Custom extends Schema {
|
|
2939
|
+
/**
|
|
2940
|
+
* @param {(o:any) => boolean} check
|
|
2941
|
+
*/
|
|
2942
|
+
constructor (check) {
|
|
2943
|
+
super();
|
|
2944
|
+
/**
|
|
2945
|
+
* @type {(o:any) => boolean}
|
|
2946
|
+
*/
|
|
2947
|
+
this.shape = check;
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
/**
|
|
2951
|
+
* @param {any} o
|
|
2952
|
+
* @param {ValidationError} err
|
|
2953
|
+
* @return {o is any}
|
|
2954
|
+
*/
|
|
2955
|
+
check (o, err) {
|
|
2956
|
+
const c = this.shape(o);
|
|
2957
|
+
/* c8 ignore next */
|
|
2958
|
+
!c && err?.extend(null, 'custom prop', o?.constructor.name, 'failed to check custom prop');
|
|
2959
|
+
return c
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
/**
|
|
2964
|
+
* @param {(o:any) => boolean} check
|
|
2965
|
+
* @return {Schema<any>}
|
|
2966
|
+
*/
|
|
2967
|
+
const $custom = (check) => new $Custom(check);
|
|
2968
|
+
$constructedBy($Custom);
|
|
2969
|
+
|
|
2970
|
+
/**
|
|
2971
|
+
* @template {Primitive} T
|
|
2972
|
+
* @extends {Schema<T>}
|
|
2973
|
+
*/
|
|
2974
|
+
class $Literal extends Schema {
|
|
2975
|
+
/**
|
|
2976
|
+
* @param {Array<T>} literals
|
|
2977
|
+
*/
|
|
2978
|
+
constructor (literals) {
|
|
2979
|
+
super();
|
|
2980
|
+
this.shape = literals;
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
/**
|
|
2984
|
+
*
|
|
2985
|
+
* @param {any} o
|
|
2986
|
+
* @param {ValidationError} [err]
|
|
2987
|
+
* @return {o is T}
|
|
2988
|
+
*/
|
|
2989
|
+
check (o, err) {
|
|
2990
|
+
const c = this.shape.some(a => a === o);
|
|
2991
|
+
/* c8 ignore next */
|
|
2992
|
+
!c && err?.extend(null, this.shape.join(' | '), o.toString());
|
|
2993
|
+
return c
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
/**
|
|
2998
|
+
* @template {Primitive[]} T
|
|
2999
|
+
* @param {T} literals
|
|
3000
|
+
* @return {CastToSchema<$Literal<T[number]>>}
|
|
3001
|
+
*/
|
|
3002
|
+
const $literal = (...literals) => new $Literal(literals);
|
|
3003
|
+
const $$literal = $constructedBy($Literal);
|
|
3004
|
+
|
|
3005
|
+
/**
|
|
3006
|
+
* @template {Array<string|Schema<string|number>>} Ts
|
|
3007
|
+
* @typedef {Ts extends [] ? `` : (Ts extends [infer T] ? (Unwrap<T> extends (string|number) ? Unwrap<T> : never) : (Ts extends [infer T1, ...infer Rest] ? `${Unwrap<T1> extends (string|number) ? Unwrap<T1> : never}${Rest extends Array<string|Schema<string|number>> ? CastStringTemplateArgsToTemplate<Rest> : never}` : never))} CastStringTemplateArgsToTemplate
|
|
3008
|
+
*/
|
|
3009
|
+
|
|
3010
|
+
/**
|
|
3011
|
+
* @param {string} str
|
|
3012
|
+
* @return {string}
|
|
3013
|
+
*/
|
|
3014
|
+
const _regexEscape = /** @type {any} */ (RegExp).escape || /** @type {(str:string) => string} */ (str =>
|
|
3015
|
+
str.replace(/[().|&,$^[\]]/g, s => '\\' + s)
|
|
3016
|
+
);
|
|
3017
|
+
|
|
3018
|
+
/**
|
|
3019
|
+
* @param {string|Schema<any>} s
|
|
3020
|
+
* @return {string[]}
|
|
3021
|
+
*/
|
|
3022
|
+
const _schemaStringTemplateToRegex = s => {
|
|
3023
|
+
if ($string.check(s)) {
|
|
3024
|
+
return [_regexEscape(s)]
|
|
3025
|
+
}
|
|
3026
|
+
if ($$literal.check(s)) {
|
|
3027
|
+
return /** @type {Array<string|number>} */ (s.shape).map(v => v + '')
|
|
3028
|
+
}
|
|
3029
|
+
if ($$number.check(s)) {
|
|
3030
|
+
return ['[+-]?\\d+.?\\d*']
|
|
3031
|
+
}
|
|
3032
|
+
if ($$string.check(s)) {
|
|
3033
|
+
return ['.*']
|
|
3034
|
+
}
|
|
3035
|
+
if ($$union.check(s)) {
|
|
3036
|
+
return s.shape.map(_schemaStringTemplateToRegex).flat(1)
|
|
3037
|
+
}
|
|
3038
|
+
/* c8 ignore next 2 */
|
|
3039
|
+
// unexpected schema structure (only supports unions and string in literal types)
|
|
3040
|
+
unexpectedCase();
|
|
3041
|
+
};
|
|
3042
|
+
|
|
3043
|
+
/**
|
|
3044
|
+
* @template {Array<string|Schema<string|number>>} T
|
|
3045
|
+
* @extends {Schema<CastStringTemplateArgsToTemplate<T>>}
|
|
3046
|
+
*/
|
|
3047
|
+
class $StringTemplate extends Schema {
|
|
3048
|
+
/**
|
|
3049
|
+
* @param {T} shape
|
|
3050
|
+
*/
|
|
3051
|
+
constructor (shape) {
|
|
3052
|
+
super();
|
|
3053
|
+
this.shape = shape;
|
|
3054
|
+
this._r = new RegExp('^' + shape.map(_schemaStringTemplateToRegex).map(opts => `(${opts.join('|')})`).join('') + '$');
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
/**
|
|
3058
|
+
* @param {any} o
|
|
3059
|
+
* @param {ValidationError} [err]
|
|
3060
|
+
* @return {o is CastStringTemplateArgsToTemplate<T>}
|
|
3061
|
+
*/
|
|
3062
|
+
check (o, err) {
|
|
3063
|
+
const c = this._r.exec(o) != null;
|
|
3064
|
+
/* c8 ignore next */
|
|
3065
|
+
!c && err?.extend(null, this._r.toString(), o.toString(), 'String doesn\'t match string template.');
|
|
3066
|
+
return c
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
$constructedBy($StringTemplate);
|
|
3070
|
+
|
|
3071
|
+
const isOptionalSymbol = Symbol('optional');
|
|
3072
|
+
/**
|
|
3073
|
+
* @template {Schema<any>} S
|
|
3074
|
+
* @extends Schema<Unwrap<S>|undefined>
|
|
3075
|
+
*/
|
|
3076
|
+
class $Optional extends Schema {
|
|
3077
|
+
/**
|
|
3078
|
+
* @param {S} shape
|
|
3079
|
+
*/
|
|
3080
|
+
constructor (shape) {
|
|
3081
|
+
super();
|
|
3082
|
+
this.shape = shape;
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
/**
|
|
3086
|
+
* @param {any} o
|
|
3087
|
+
* @param {ValidationError} [err]
|
|
3088
|
+
* @return {o is (Unwrap<S>|undefined)}
|
|
3089
|
+
*/
|
|
3090
|
+
check (o, err) {
|
|
3091
|
+
const c = o === undefined || this.shape.check(o);
|
|
3092
|
+
/* c8 ignore next */
|
|
3093
|
+
!c && err?.extend(null, 'undefined (optional)', '()');
|
|
3094
|
+
return c
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
get [isOptionalSymbol] () { return true }
|
|
3098
|
+
}
|
|
3099
|
+
const $$optional = $constructedBy($Optional);
|
|
3100
|
+
|
|
3101
|
+
/**
|
|
3102
|
+
* @extends Schema<never>
|
|
3103
|
+
*/
|
|
3104
|
+
class $Never extends Schema {
|
|
3105
|
+
/**
|
|
3106
|
+
* @param {any} _o
|
|
3107
|
+
* @param {ValidationError} [err]
|
|
3108
|
+
* @return {_o is never}
|
|
3109
|
+
*/
|
|
3110
|
+
check (_o, err) {
|
|
3111
|
+
/* c8 ignore next */
|
|
3112
|
+
err?.extend(null, 'never', typeof _o);
|
|
3113
|
+
return false
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
$constructedBy($Never);
|
|
3117
|
+
|
|
3118
|
+
/**
|
|
3119
|
+
* @template {{ [key: string|symbol|number]: Schema<any> }} S
|
|
3120
|
+
* @typedef {{ [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? Key : never]?: S[Key] extends $Optional<Schema<infer Type>> ? Type : never } & { [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? never : Key]: S[Key] extends Schema<infer Type> ? Type : never }} $ObjectToType
|
|
3121
|
+
*/
|
|
3122
|
+
|
|
3123
|
+
/**
|
|
3124
|
+
* @template {{[key:string|symbol|number]: Schema<any>}} S
|
|
3125
|
+
* @extends {Schema<$ObjectToType<S>>}
|
|
3126
|
+
*/
|
|
3127
|
+
let $Object$3 = class $Object extends Schema {
|
|
3128
|
+
/**
|
|
3129
|
+
* @param {S} shape
|
|
3130
|
+
* @param {boolean} partial
|
|
3131
|
+
*/
|
|
3132
|
+
constructor (shape, partial = false) {
|
|
3133
|
+
super();
|
|
3134
|
+
/**
|
|
3135
|
+
* @type {S}
|
|
3136
|
+
*/
|
|
3137
|
+
this.shape = shape;
|
|
3138
|
+
this._isPartial = partial;
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
static _dilutes = true
|
|
3142
|
+
|
|
3143
|
+
/**
|
|
3144
|
+
* @type {Schema<Partial<$ObjectToType<S>>>}
|
|
3145
|
+
*/
|
|
3146
|
+
get partial () {
|
|
3147
|
+
return new $Object(this.shape, true)
|
|
3148
|
+
}
|
|
3149
|
+
|
|
3150
|
+
/**
|
|
3151
|
+
* @param {any} o
|
|
3152
|
+
* @param {ValidationError} err
|
|
3153
|
+
* @return {o is $ObjectToType<S>}
|
|
3154
|
+
*/
|
|
3155
|
+
check (o, err) {
|
|
3156
|
+
if (o == null) {
|
|
3157
|
+
/* c8 ignore next */
|
|
3158
|
+
err?.extend(null, 'object', 'null');
|
|
3159
|
+
return false
|
|
3160
|
+
}
|
|
3161
|
+
return every(this.shape, (vv, vk) => {
|
|
3162
|
+
const c = (this._isPartial && !hasProperty(o, vk)) || vv.check(o[vk], err);
|
|
3163
|
+
!c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], 'Object property does not match');
|
|
3164
|
+
return c
|
|
3165
|
+
})
|
|
3166
|
+
}
|
|
3167
|
+
};
|
|
3168
|
+
|
|
3169
|
+
/**
|
|
3170
|
+
* @template S
|
|
3171
|
+
* @typedef {Schema<{ [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? Key : never]?: S[Key] extends $Optional<Schema<infer Type>> ? Type : never } & { [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? never : Key]: S[Key] extends Schema<infer Type> ? Type : never }>} _ObjectDefToSchema
|
|
3172
|
+
*/
|
|
3173
|
+
|
|
3174
|
+
// I used an explicit type annotation instead of $ObjectToType, so that the user doesn't see the
|
|
3175
|
+
// weird type definitions when inspecting type definions.
|
|
3176
|
+
/**
|
|
3177
|
+
* @template {{ [key:string|symbol|number]: Schema<any> }} S
|
|
3178
|
+
* @param {S} def
|
|
3179
|
+
* @return {_ObjectDefToSchema<S> extends Schema<infer S> ? Schema<{ [K in keyof S]: S[K] }> : never}
|
|
3180
|
+
*/
|
|
3181
|
+
const $object = def => /** @type {any} */ (new $Object$3(def));
|
|
3182
|
+
const $$object = $constructedBy($Object$3);
|
|
3183
|
+
/**
|
|
3184
|
+
* @type {Schema<{[key:string]: any}>}
|
|
3185
|
+
*/
|
|
3186
|
+
const $objectAny = $custom(o => o != null && (o.constructor === Object || o.constructor == null));
|
|
3187
|
+
|
|
3188
|
+
/**
|
|
3189
|
+
* @template {Schema<string|number|symbol>} Keys
|
|
3190
|
+
* @template {Schema<any>} Values
|
|
3191
|
+
* @extends {Schema<{ [key in Unwrap<Keys>]: Unwrap<Values> }>}
|
|
3192
|
+
*/
|
|
3193
|
+
class $Record extends Schema {
|
|
3194
|
+
/**
|
|
3195
|
+
* @param {Keys} keys
|
|
3196
|
+
* @param {Values} values
|
|
3197
|
+
*/
|
|
3198
|
+
constructor (keys, values) {
|
|
3199
|
+
super();
|
|
3200
|
+
this.shape = {
|
|
3201
|
+
keys, values
|
|
3202
|
+
};
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
/**
|
|
3206
|
+
* @param {any} o
|
|
3207
|
+
* @param {ValidationError} err
|
|
3208
|
+
* @return {o is { [key in Unwrap<Keys>]: Unwrap<Values> }}
|
|
3209
|
+
*/
|
|
3210
|
+
check (o, err) {
|
|
3211
|
+
return o != null && every(o, (vv, vk) => {
|
|
3212
|
+
const ck = this.shape.keys.check(vk, err);
|
|
3213
|
+
/* c8 ignore next */
|
|
3214
|
+
!ck && err?.extend(vk + '', 'Record', typeof o, ck ? 'Key doesn\'t match schema' : 'Value doesn\'t match value');
|
|
3215
|
+
return ck && this.shape.values.check(vv, err)
|
|
3216
|
+
})
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
/**
|
|
3221
|
+
* @template {Schema<string|number|symbol>} Keys
|
|
3222
|
+
* @template {Schema<any>} Values
|
|
3223
|
+
* @param {Keys} keys
|
|
3224
|
+
* @param {Values} values
|
|
3225
|
+
* @return {CastToSchema<$Record<Keys,Values>>}
|
|
3226
|
+
*/
|
|
3227
|
+
const $record = (keys, values) => new $Record(keys, values);
|
|
3228
|
+
const $$record = $constructedBy($Record);
|
|
3229
|
+
|
|
3230
|
+
/**
|
|
3231
|
+
* @template {Schema<any>[]} S
|
|
3232
|
+
* @extends {Schema<{ [Key in keyof S]: S[Key] extends Schema<infer Type> ? Type : never }>}
|
|
3233
|
+
*/
|
|
3234
|
+
class $Tuple extends Schema {
|
|
3235
|
+
/**
|
|
3236
|
+
* @param {S} shape
|
|
3237
|
+
*/
|
|
3238
|
+
constructor (shape) {
|
|
3239
|
+
super();
|
|
3240
|
+
this.shape = shape;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
/**
|
|
3244
|
+
* @param {any} o
|
|
3245
|
+
* @param {ValidationError} err
|
|
3246
|
+
* @return {o is { [K in keyof S]: S[K] extends Schema<infer Type> ? Type : never }}
|
|
3247
|
+
*/
|
|
3248
|
+
check (o, err) {
|
|
3249
|
+
return o != null && every(this.shape, (vv, vk) => {
|
|
3250
|
+
const c = /** @type {Schema<any>} */ (vv).check(o[vk], err);
|
|
3251
|
+
/* c8 ignore next */
|
|
3252
|
+
!c && err?.extend(vk.toString(), 'Tuple', typeof vv);
|
|
3253
|
+
return c
|
|
3254
|
+
})
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
/**
|
|
3259
|
+
* @template {Array<Schema<any>>} T
|
|
3260
|
+
* @param {T} def
|
|
3261
|
+
* @return {CastToSchema<$Tuple<T>>}
|
|
3262
|
+
*/
|
|
3263
|
+
const $tuple = (...def) => new $Tuple(def);
|
|
3264
|
+
$constructedBy($Tuple);
|
|
3265
|
+
|
|
3266
|
+
/**
|
|
3267
|
+
* @template {Schema<any>} S
|
|
3268
|
+
* @extends {Schema<Array<S extends Schema<infer T> ? T : never>>}
|
|
3269
|
+
*/
|
|
3270
|
+
class $Array extends Schema {
|
|
3271
|
+
/**
|
|
3272
|
+
* @param {Array<S>} v
|
|
3273
|
+
*/
|
|
3274
|
+
constructor (v) {
|
|
3275
|
+
super();
|
|
3276
|
+
/**
|
|
3277
|
+
* @type {Schema<S extends Schema<infer T> ? T : never>}
|
|
3278
|
+
*/
|
|
3279
|
+
this.shape = v.length === 1 ? v[0] : new $Union(v);
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
/**
|
|
3283
|
+
* @param {any} o
|
|
3284
|
+
* @param {ValidationError} [err]
|
|
3285
|
+
* @return {o is Array<S extends Schema<infer T> ? T : never>} o
|
|
3286
|
+
*/
|
|
3287
|
+
check (o, err) {
|
|
3288
|
+
const c = isArray$1(o) && every$1(o, oi => this.shape.check(oi));
|
|
3289
|
+
/* c8 ignore next */
|
|
3290
|
+
!c && err?.extend(null, 'Array', '');
|
|
3291
|
+
return c
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3295
|
+
/**
|
|
3296
|
+
* @template {Array<Schema<any>>} T
|
|
3297
|
+
* @param {T} def
|
|
3298
|
+
* @return {Schema<Array<T extends Array<Schema<infer S>> ? S : never>>}
|
|
3299
|
+
*/
|
|
3300
|
+
const $array = (...def) => new $Array(def);
|
|
3301
|
+
const $$array = $constructedBy($Array);
|
|
3302
|
+
/**
|
|
3303
|
+
* @type {Schema<Array<any>>}
|
|
3304
|
+
*/
|
|
3305
|
+
const $arrayAny = $custom(o => isArray$1(o));
|
|
3306
|
+
|
|
3307
|
+
/**
|
|
3308
|
+
* @template T
|
|
3309
|
+
* @extends {Schema<T>}
|
|
3310
|
+
*/
|
|
3311
|
+
class $InstanceOf extends Schema {
|
|
3312
|
+
/**
|
|
3313
|
+
* @param {new (...args:any) => T} constructor
|
|
3314
|
+
* @param {((o:T) => boolean)|null} check
|
|
3315
|
+
*/
|
|
3316
|
+
constructor (constructor, check) {
|
|
3317
|
+
super();
|
|
3318
|
+
this.shape = constructor;
|
|
3319
|
+
this._c = check;
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
/**
|
|
3323
|
+
* @param {any} o
|
|
3324
|
+
* @param {ValidationError} err
|
|
3325
|
+
* @return {o is T}
|
|
3326
|
+
*/
|
|
3327
|
+
check (o, err) {
|
|
3328
|
+
const c = o instanceof this.shape && (this._c == null || this._c(o));
|
|
3329
|
+
/* c8 ignore next */
|
|
3330
|
+
!c && err?.extend(null, this.shape.name, o?.constructor.name);
|
|
3331
|
+
return c
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3335
|
+
/**
|
|
3336
|
+
* @template T
|
|
3337
|
+
* @param {new (...args:any) => T} c
|
|
3338
|
+
* @param {((o:T) => boolean)|null} check
|
|
3339
|
+
* @return {Schema<T>}
|
|
3340
|
+
*/
|
|
3341
|
+
const $instanceOf = (c, check = null) => new $InstanceOf(c, check);
|
|
3342
|
+
$constructedBy($InstanceOf);
|
|
3343
|
+
|
|
3344
|
+
const $$schema = $instanceOf(Schema);
|
|
3345
|
+
|
|
3346
|
+
/**
|
|
3347
|
+
* @template {Schema<any>[]} Args
|
|
3348
|
+
* @typedef {(...args:UnwrapArray<TuplePop<Args>>)=>Unwrap<TupleLast<Args>>} _LArgsToLambdaDef
|
|
3349
|
+
*/
|
|
3350
|
+
|
|
3351
|
+
/**
|
|
3352
|
+
* @template {Array<Schema<any>>} Args
|
|
3353
|
+
* @extends {Schema<_LArgsToLambdaDef<Args>>}
|
|
3354
|
+
*/
|
|
3355
|
+
class $Lambda extends Schema {
|
|
3356
|
+
/**
|
|
3357
|
+
* @param {Args} args
|
|
3358
|
+
*/
|
|
3359
|
+
constructor (args) {
|
|
3360
|
+
super();
|
|
3361
|
+
this.len = args.length - 1;
|
|
3362
|
+
this.args = $tuple(...args.slice(-1));
|
|
3363
|
+
this.res = args[this.len];
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
/**
|
|
3367
|
+
* @param {any} f
|
|
3368
|
+
* @param {ValidationError} err
|
|
3369
|
+
* @return {f is _LArgsToLambdaDef<Args>}
|
|
3370
|
+
*/
|
|
3371
|
+
check (f, err) {
|
|
3372
|
+
const c = f.constructor === Function && f.length <= this.len;
|
|
3373
|
+
/* c8 ignore next */
|
|
3374
|
+
!c && err?.extend(null, 'function', typeof f);
|
|
3375
|
+
return c
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
const $$lambda = $constructedBy($Lambda);
|
|
3379
|
+
|
|
3380
|
+
/**
|
|
3381
|
+
* @type {Schema<Function>}
|
|
3382
|
+
*/
|
|
3383
|
+
const $function = $custom(o => typeof o === 'function');
|
|
3384
|
+
|
|
3385
|
+
/**
|
|
3386
|
+
* @template {Array<Schema<any>>} T
|
|
3387
|
+
* @extends {Schema<Intersect<UnwrapArray<T>>>}
|
|
3388
|
+
*/
|
|
3389
|
+
class $Intersection extends Schema {
|
|
3390
|
+
/**
|
|
3391
|
+
* @param {T} v
|
|
3392
|
+
*/
|
|
3393
|
+
constructor (v) {
|
|
3394
|
+
super();
|
|
3395
|
+
/**
|
|
3396
|
+
* @type {T}
|
|
3397
|
+
*/
|
|
3398
|
+
this.shape = v;
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
/**
|
|
3402
|
+
* @param {any} o
|
|
3403
|
+
* @param {ValidationError} [err]
|
|
3404
|
+
* @return {o is Intersect<UnwrapArray<T>>}
|
|
3405
|
+
*/
|
|
3406
|
+
check (o, err) {
|
|
3407
|
+
// @ts-ignore
|
|
3408
|
+
const c = every$1(this.shape, check => check.check(o, err));
|
|
3409
|
+
/* c8 ignore next */
|
|
3410
|
+
!c && err?.extend(null, 'Intersectinon', typeof o);
|
|
3411
|
+
return c
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
$constructedBy($Intersection, o => o.shape.length > 0); // Intersection with length=0 is considered "any"
|
|
3415
|
+
|
|
3416
|
+
/**
|
|
3417
|
+
* @template S
|
|
3418
|
+
* @extends {Schema<S>}
|
|
3419
|
+
*/
|
|
3420
|
+
class $Union extends Schema {
|
|
3421
|
+
static _dilutes = true
|
|
3422
|
+
|
|
3423
|
+
/**
|
|
3424
|
+
* @param {Array<Schema<S>>} v
|
|
3425
|
+
*/
|
|
3426
|
+
constructor (v) {
|
|
3427
|
+
super();
|
|
3428
|
+
this.shape = v;
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
/**
|
|
3432
|
+
* @param {any} o
|
|
3433
|
+
* @param {ValidationError} [err]
|
|
3434
|
+
* @return {o is S}
|
|
3435
|
+
*/
|
|
3436
|
+
check (o, err) {
|
|
3437
|
+
const c = some(this.shape, (vv) => vv.check(o, err));
|
|
3438
|
+
err?.extend(null, 'Union', typeof o);
|
|
3439
|
+
return c
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
|
|
3443
|
+
/**
|
|
3444
|
+
* @template {Array<any>} T
|
|
3445
|
+
* @param {T} schemas
|
|
3446
|
+
* @return {CastToSchema<$Union<Unwrap<ReadSchema<T>>>>}
|
|
3447
|
+
*/
|
|
3448
|
+
const $union = (...schemas) => schemas.findIndex($s => $$union.check($s)) >= 0
|
|
3449
|
+
? $union(...schemas.map($s => $($s)).map($s => $$union.check($s) ? $s.shape : [$s]).flat(1))
|
|
3450
|
+
: (schemas.length === 1
|
|
3451
|
+
? schemas[0]
|
|
3452
|
+
: new $Union(schemas));
|
|
3453
|
+
const $$union = /** @type {Schema<$Union<any>>} */ ($constructedBy($Union));
|
|
3454
|
+
|
|
3455
|
+
const _t = () => true;
|
|
3456
|
+
/**
|
|
3457
|
+
* @type {Schema<any>}
|
|
3458
|
+
*/
|
|
3459
|
+
const $any = $custom(_t);
|
|
3460
|
+
const $$any = /** @type {Schema<Schema<any>>} */ ($constructedBy($Custom, o => o.shape === _t));
|
|
3461
|
+
|
|
3462
|
+
/**
|
|
3463
|
+
* @type {Schema<bigint>}
|
|
3464
|
+
*/
|
|
3465
|
+
const $bigint = $custom(o => typeof o === 'bigint');
|
|
3466
|
+
const $$bigint = /** @type {Schema<Schema<BigInt>>} */ ($custom(o => o === $bigint));
|
|
3467
|
+
|
|
3468
|
+
/**
|
|
3469
|
+
* @type {Schema<symbol>}
|
|
3470
|
+
*/
|
|
3471
|
+
const $symbol = $custom(o => typeof o === 'symbol');
|
|
3472
|
+
/** @type {Schema<Schema<Symbol>>} */ ($custom(o => o === $symbol));
|
|
3473
|
+
|
|
3474
|
+
/**
|
|
3475
|
+
* @type {Schema<number>}
|
|
3476
|
+
*/
|
|
3477
|
+
const $number = $custom(o => typeof o === 'number');
|
|
3478
|
+
const $$number = /** @type {Schema<Schema<number>>} */ ($custom(o => o === $number));
|
|
3479
|
+
|
|
3480
|
+
/**
|
|
3481
|
+
* @type {Schema<string>}
|
|
3482
|
+
*/
|
|
3483
|
+
const $string = $custom(o => typeof o === 'string');
|
|
3484
|
+
const $$string = /** @type {Schema<Schema<string>>} */ ($custom(o => o === $string));
|
|
3485
|
+
|
|
3486
|
+
/**
|
|
3487
|
+
* @type {Schema<boolean>}
|
|
3488
|
+
*/
|
|
3489
|
+
const $boolean = $custom(o => typeof o === 'boolean');
|
|
3490
|
+
const $$boolean = /** @type {Schema<Schema<Boolean>>} */ ($custom(o => o === $boolean));
|
|
3491
|
+
|
|
3492
|
+
/**
|
|
3493
|
+
* @type {Schema<undefined>}
|
|
3494
|
+
*/
|
|
3495
|
+
const $undefined = $literal(undefined);
|
|
3496
|
+
/** @type {Schema<Schema<undefined>>} */ ($constructedBy($Literal, o => o.shape.length === 1 && o.shape[0] === undefined));
|
|
3497
|
+
|
|
3498
|
+
/**
|
|
3499
|
+
* @type {Schema<void>}
|
|
3500
|
+
*/
|
|
3501
|
+
$literal(undefined);
|
|
3502
|
+
|
|
3503
|
+
const $null = $literal(null);
|
|
3504
|
+
const $$null = /** @type {Schema<Schema<null>>} */ ($constructedBy($Literal, o => o.shape.length === 1 && o.shape[0] === null));
|
|
3505
|
+
|
|
3506
|
+
$constructedBy(Uint8Array);
|
|
3507
|
+
/** @type {Schema<Schema<Uint8Array>>} */ ($constructedBy($ConstructedBy, o => o.shape === Uint8Array));
|
|
3508
|
+
|
|
3509
|
+
/**
|
|
3510
|
+
* @type {Schema<Primitive>}
|
|
3511
|
+
*/
|
|
3512
|
+
const $primitive = $union($number, $string, $null, $undefined, $bigint, $boolean, $symbol);
|
|
3513
|
+
|
|
3514
|
+
/**
|
|
3515
|
+
* @typedef {JSON[]} JSONArray
|
|
3516
|
+
*/
|
|
3517
|
+
/**
|
|
3518
|
+
* @typedef {Primitive|JSONArray|{ [key:string]:JSON }} JSON
|
|
3519
|
+
*/
|
|
3520
|
+
/**
|
|
3521
|
+
* @type {Schema<null|number|string|boolean|JSON[]|{[key:string]:JSON}>}
|
|
3522
|
+
*/
|
|
3523
|
+
(() => {
|
|
3524
|
+
const $jsonArr = /** @type {$Array<$any>} */ ($array($any));
|
|
3525
|
+
const $jsonRecord = /** @type {$Record<$string,$any>} */ ($record($string, $any));
|
|
3526
|
+
const $json = $union($number, $string, $null, $boolean, $jsonArr, $jsonRecord);
|
|
3527
|
+
$jsonArr.shape = $json;
|
|
3528
|
+
$jsonRecord.shape.values = $json;
|
|
3529
|
+
return $json
|
|
3530
|
+
})();
|
|
3531
|
+
|
|
3532
|
+
/**
|
|
3533
|
+
* @template {any} IN
|
|
3534
|
+
* @typedef {IN extends Schema<any> ? IN
|
|
3535
|
+
* : (IN extends string|number|boolean|null ? Schema<IN>
|
|
3536
|
+
* : (IN extends new (...args:any[])=>any ? Schema<InstanceType<IN>>
|
|
3537
|
+
* : (IN extends any[] ? Schema<{ [K in keyof IN]: Unwrap<ReadSchema<IN[K]>> }[number]>
|
|
3538
|
+
* : (IN extends object ? (_ObjectDefToSchema<{[K in keyof IN]:ReadSchema<IN[K]>}> extends Schema<infer S> ? Schema<{ [K in keyof S]: S[K] }> : never)
|
|
3539
|
+
* : never)
|
|
3540
|
+
* )
|
|
3541
|
+
* )
|
|
3542
|
+
* )
|
|
3543
|
+
* } ReadSchemaOld
|
|
3544
|
+
*/
|
|
3545
|
+
|
|
3546
|
+
/**
|
|
3547
|
+
* @template {any} IN
|
|
3548
|
+
* @typedef {[Extract<IN,Schema<any>>,Extract<IN,string|number|boolean|null>,Extract<IN,new (...args:any[])=>any>,Extract<IN,any[]>,Extract<Exclude<IN,Schema<any>|string|number|boolean|null|(new (...args:any[])=>any)|any[]>,object>] extends [infer Schemas, infer Primitives, infer Constructors, infer Arrs, infer Obj]
|
|
3549
|
+
* ? Schema<
|
|
3550
|
+
* (Schemas extends Schema<infer S> ? S : never)
|
|
3551
|
+
* | Primitives
|
|
3552
|
+
* | (Constructors extends new (...args:any[])=>any ? InstanceType<Constructors> : never)
|
|
3553
|
+
* | (Arrs extends any[] ? { [K in keyof Arrs]: Unwrap<ReadSchema<Arrs[K]>> }[number] : never)
|
|
3554
|
+
* | (Obj extends object ? Unwrap<(_ObjectDefToSchema<{[K in keyof Obj]:ReadSchema<Obj[K]>}> extends Schema<infer S> ? Schema<{ [K in keyof S]: S[K] }> : never)> : never)>
|
|
3555
|
+
* : never
|
|
3556
|
+
* } ReadSchema
|
|
3557
|
+
*/
|
|
3558
|
+
|
|
3559
|
+
/**
|
|
3560
|
+
* @typedef {ReadSchema<{x:42}|{y:99}|Schema<string>|[1,2,{}]>} Q
|
|
3561
|
+
*/
|
|
3562
|
+
|
|
3563
|
+
/**
|
|
3564
|
+
* @template IN
|
|
3565
|
+
* @param {IN} o
|
|
3566
|
+
* @return {ReadSchema<IN>}
|
|
3567
|
+
*/
|
|
3568
|
+
const $ = o => {
|
|
3569
|
+
if ($$schema.check(o)) {
|
|
3570
|
+
return /** @type {any} */ (o)
|
|
3571
|
+
} else if ($objectAny.check(o)) {
|
|
3572
|
+
/**
|
|
3573
|
+
* @type {any}
|
|
3574
|
+
*/
|
|
3575
|
+
const o2 = {};
|
|
3576
|
+
for (const k in o) {
|
|
3577
|
+
o2[k] = $(o[k]);
|
|
3578
|
+
}
|
|
3579
|
+
return /** @type {any} */ ($object(o2))
|
|
3580
|
+
} else if ($arrayAny.check(o)) {
|
|
3581
|
+
return /** @type {any} */ ($union(...o.map($)))
|
|
3582
|
+
} else if ($primitive.check(o)) {
|
|
3583
|
+
return /** @type {any} */ ($literal(o))
|
|
3584
|
+
} else if ($function.check(o)) {
|
|
3585
|
+
return /** @type {any} */ ($constructedBy(/** @type {any} */ (o)))
|
|
3586
|
+
}
|
|
3587
|
+
/* c8 ignore next */
|
|
3588
|
+
unexpectedCase();
|
|
3589
|
+
};
|
|
3590
|
+
|
|
3591
|
+
/* c8 ignore start */
|
|
3592
|
+
/**
|
|
3593
|
+
* Assert that a variable is of this specific type.
|
|
3594
|
+
* The assertion check is only performed in non-production environments.
|
|
2328
3595
|
*
|
|
2329
|
-
* @
|
|
3596
|
+
* @type {<T>(o:any,schema:Schema<T>) => asserts o is T}
|
|
2330
3597
|
*/
|
|
2331
|
-
|
|
3598
|
+
const assert = production
|
|
3599
|
+
? () => {}
|
|
3600
|
+
: (o, schema) => {
|
|
3601
|
+
const err = new ValidationError();
|
|
3602
|
+
if (!schema.check(o, err)) {
|
|
3603
|
+
throw create$3(`Expected value to be of type ${schema.constructor.name}.\n${err.toString()}`)
|
|
3604
|
+
}
|
|
3605
|
+
};
|
|
3606
|
+
/* c8 ignore end */
|
|
2332
3607
|
|
|
2333
3608
|
/**
|
|
2334
|
-
* @
|
|
3609
|
+
* @template In
|
|
3610
|
+
* @template Out
|
|
3611
|
+
* @typedef {{ if: Schema<In>, h: (o:In,state?:any)=>Out }} Pattern
|
|
2335
3612
|
*/
|
|
2336
|
-
const createUint8ArrayFromLen = len => new Uint8Array(len);
|
|
2337
3613
|
|
|
2338
3614
|
/**
|
|
2339
|
-
*
|
|
2340
|
-
*
|
|
2341
|
-
* @
|
|
2342
|
-
* @return {Uint8Array}
|
|
3615
|
+
* @template {Pattern<any,any>} P
|
|
3616
|
+
* @template In
|
|
3617
|
+
* @typedef {ReturnType<Extract<P,Pattern<In extends number ? number : (In extends string ? string : In),any>>['h']>} PatternMatchResult
|
|
2343
3618
|
*/
|
|
2344
|
-
const copyUint8Array = uint8Array => {
|
|
2345
|
-
const newBuf = createUint8ArrayFromLen(uint8Array.byteLength);
|
|
2346
|
-
newBuf.set(uint8Array);
|
|
2347
|
-
return newBuf
|
|
2348
|
-
};
|
|
2349
3619
|
|
|
2350
3620
|
/**
|
|
2351
|
-
*
|
|
2352
|
-
*
|
|
2353
|
-
* @
|
|
3621
|
+
* @todo move this to separate library
|
|
3622
|
+
* @template {any} [State=undefined]
|
|
3623
|
+
* @template {Pattern<any,any>} [Patterns=never]
|
|
2354
3624
|
*/
|
|
3625
|
+
class PatternMatcher {
|
|
3626
|
+
/**
|
|
3627
|
+
* @param {Schema<State>} [$state]
|
|
3628
|
+
*/
|
|
3629
|
+
constructor ($state) {
|
|
3630
|
+
/**
|
|
3631
|
+
* @type {Array<Patterns>}
|
|
3632
|
+
*/
|
|
3633
|
+
this.patterns = [];
|
|
3634
|
+
this.$state = $state;
|
|
3635
|
+
}
|
|
2355
3636
|
|
|
2356
|
-
/**
|
|
2357
|
-
* @template L,R
|
|
2358
|
-
*/
|
|
2359
|
-
class Pair {
|
|
2360
3637
|
/**
|
|
2361
|
-
* @
|
|
2362
|
-
* @
|
|
3638
|
+
* @template P
|
|
3639
|
+
* @template R
|
|
3640
|
+
* @param {P} pattern
|
|
3641
|
+
* @param {(o:NoInfer<Unwrap<ReadSchema<P>>>,s:State)=>R} handler
|
|
3642
|
+
* @return {PatternMatcher<State,Patterns|Pattern<Unwrap<ReadSchema<P>>,R>>}
|
|
2363
3643
|
*/
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
this.
|
|
3644
|
+
if (pattern, handler) {
|
|
3645
|
+
// @ts-ignore
|
|
3646
|
+
this.patterns.push({ if: $(pattern), h: handler });
|
|
3647
|
+
// @ts-ignore
|
|
3648
|
+
return this
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
/**
|
|
3652
|
+
* @template R
|
|
3653
|
+
* @param {(o:any,s:State)=>R} h
|
|
3654
|
+
*/
|
|
3655
|
+
else (h) {
|
|
3656
|
+
return this.if($any, h)
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
/**
|
|
3660
|
+
* @return {State extends undefined
|
|
3661
|
+
* ? <In extends Unwrap<Patterns['if']>>(o:In,state?:undefined)=>PatternMatchResult<Patterns,In>
|
|
3662
|
+
* : <In extends Unwrap<Patterns['if']>>(o:In,state:State)=>PatternMatchResult<Patterns,In>}
|
|
3663
|
+
*/
|
|
3664
|
+
done () {
|
|
3665
|
+
// @ts-ignore
|
|
3666
|
+
return /** @type {any} */ (o, s) => {
|
|
3667
|
+
for (let i = 0; i < this.patterns.length; i++) {
|
|
3668
|
+
const p = this.patterns[i];
|
|
3669
|
+
if (p.if.check(o)) {
|
|
3670
|
+
// @ts-ignore
|
|
3671
|
+
return p.h(o, s)
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
throw create$3('Unhandled pattern')
|
|
3675
|
+
}
|
|
2367
3676
|
}
|
|
2368
3677
|
}
|
|
2369
3678
|
|
|
2370
3679
|
/**
|
|
2371
|
-
* @template
|
|
2372
|
-
* @param {
|
|
2373
|
-
* @
|
|
2374
|
-
* @return {Pair<L,R>}
|
|
3680
|
+
* @template [State=undefined]
|
|
3681
|
+
* @param {State} [state]
|
|
3682
|
+
* @return {PatternMatcher<State extends undefined ? undefined : Unwrap<ReadSchema<State>>>}
|
|
2375
3683
|
*/
|
|
2376
|
-
const
|
|
3684
|
+
const match = state => new PatternMatcher(/** @type {any} */ (state));
|
|
3685
|
+
|
|
3686
|
+
/**
|
|
3687
|
+
* Helper function to generate a (non-exhaustive) sample set from a gives schema.
|
|
3688
|
+
*
|
|
3689
|
+
* @type {<T>(o:T,gen:prng.PRNG)=>T}
|
|
3690
|
+
*/
|
|
3691
|
+
const _random = /** @type {any} */ (match(/** @type {Schema<prng.PRNG>} */ ($any))
|
|
3692
|
+
.if($$number, (_o, gen) => int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER))
|
|
3693
|
+
.if($$string, (_o, gen) => word(gen))
|
|
3694
|
+
.if($$boolean, (_o, gen) => bool(gen))
|
|
3695
|
+
.if($$bigint, (_o, gen) => BigInt(int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER)))
|
|
3696
|
+
.if($$union, (o, gen) => random(gen, oneOf(gen, o.shape)))
|
|
3697
|
+
.if($$object, (o, gen) => {
|
|
3698
|
+
/**
|
|
3699
|
+
* @type {any}
|
|
3700
|
+
*/
|
|
3701
|
+
const res = {};
|
|
3702
|
+
for (const k in o.shape) {
|
|
3703
|
+
let prop = o.shape[k];
|
|
3704
|
+
if ($$optional.check(prop)) {
|
|
3705
|
+
if (bool(gen)) { continue }
|
|
3706
|
+
prop = prop.shape;
|
|
3707
|
+
}
|
|
3708
|
+
res[k] = _random(prop, gen);
|
|
3709
|
+
}
|
|
3710
|
+
return res
|
|
3711
|
+
})
|
|
3712
|
+
.if($$array, (o, gen) => {
|
|
3713
|
+
const arr = [];
|
|
3714
|
+
const n = int32(gen, 0, 42);
|
|
3715
|
+
for (let i = 0; i < n; i++) {
|
|
3716
|
+
arr.push(random(gen, o.shape));
|
|
3717
|
+
}
|
|
3718
|
+
return arr
|
|
3719
|
+
})
|
|
3720
|
+
.if($$literal, (o, gen) => {
|
|
3721
|
+
return oneOf(gen, o.shape)
|
|
3722
|
+
})
|
|
3723
|
+
.if($$null, (o, gen) => {
|
|
3724
|
+
return null
|
|
3725
|
+
})
|
|
3726
|
+
.if($$lambda, (o, gen) => {
|
|
3727
|
+
const res = random(gen, o.res);
|
|
3728
|
+
return () => res
|
|
3729
|
+
})
|
|
3730
|
+
.if($$any, (o, gen) => random(gen, oneOf(gen, [
|
|
3731
|
+
$number, $string, $null, $undefined, $bigint, $boolean,
|
|
3732
|
+
$array($number),
|
|
3733
|
+
$record($union('a', 'b', 'c'), $number)
|
|
3734
|
+
])))
|
|
3735
|
+
.if($$record, (o, gen) => {
|
|
3736
|
+
/**
|
|
3737
|
+
* @type {any}
|
|
3738
|
+
*/
|
|
3739
|
+
const res = {};
|
|
3740
|
+
const keysN = int53(gen, 0, 3);
|
|
3741
|
+
for (let i = 0; i < keysN; i++) {
|
|
3742
|
+
const key = random(gen, o.shape.keys);
|
|
3743
|
+
const val = random(gen, o.shape.values);
|
|
3744
|
+
res[key] = val;
|
|
3745
|
+
}
|
|
3746
|
+
return res
|
|
3747
|
+
})
|
|
3748
|
+
.done());
|
|
3749
|
+
|
|
3750
|
+
/**
|
|
3751
|
+
* @template S
|
|
3752
|
+
* @param {prng.PRNG} gen
|
|
3753
|
+
* @param {S} schema
|
|
3754
|
+
* @return {Unwrap<ReadSchema<S>>}
|
|
3755
|
+
*/
|
|
3756
|
+
const random = (gen, schema) => /** @type {any} */ (_random($(schema), gen));
|
|
2377
3757
|
|
|
2378
3758
|
/* eslint-env browser */
|
|
2379
3759
|
|
|
2380
3760
|
|
|
3761
|
+
/* c8 ignore start */
|
|
3762
|
+
/**
|
|
3763
|
+
* @type {Document}
|
|
3764
|
+
*/
|
|
3765
|
+
const doc = /** @type {Document} */ (typeof document !== 'undefined' ? document : {});
|
|
3766
|
+
|
|
3767
|
+
/**
|
|
3768
|
+
* @type {$.Schema<DocumentFragment>}
|
|
3769
|
+
*/
|
|
3770
|
+
$custom(el => el.nodeType === DOCUMENT_FRAGMENT_NODE);
|
|
3771
|
+
|
|
2381
3772
|
/** @type {DOMParser} */ (typeof DOMParser !== 'undefined' ? new DOMParser() : null);
|
|
2382
3773
|
|
|
3774
|
+
/**
|
|
3775
|
+
* @type {$.Schema<Element>}
|
|
3776
|
+
*/
|
|
3777
|
+
$custom(el => el.nodeType === ELEMENT_NODE);
|
|
3778
|
+
|
|
3779
|
+
/**
|
|
3780
|
+
* @type {$.Schema<Text>}
|
|
3781
|
+
*/
|
|
3782
|
+
$custom(el => el.nodeType === TEXT_NODE);
|
|
3783
|
+
|
|
2383
3784
|
/**
|
|
2384
3785
|
* @param {Map<string,string>} m
|
|
2385
3786
|
* @return {string}
|
|
2386
3787
|
*/
|
|
2387
3788
|
const mapToStyleString = m => map(m, (value, key) => `${key}:${value};`).join('');
|
|
3789
|
+
|
|
3790
|
+
const ELEMENT_NODE = doc.ELEMENT_NODE;
|
|
3791
|
+
const TEXT_NODE = doc.TEXT_NODE;
|
|
3792
|
+
const DOCUMENT_NODE = doc.DOCUMENT_NODE;
|
|
3793
|
+
const DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE;
|
|
3794
|
+
|
|
3795
|
+
/**
|
|
3796
|
+
* @type {$.Schema<Node>}
|
|
3797
|
+
*/
|
|
3798
|
+
$custom(el => el.nodeType === DOCUMENT_NODE);
|
|
2388
3799
|
/* c8 ignore stop */
|
|
2389
3800
|
|
|
2390
3801
|
/**
|
|
@@ -5047,17 +6458,21 @@ const cleanupTransactions = (transactionCleanups, i) => {
|
|
|
5047
6458
|
// sort events by path length so that top-level events are fired first.
|
|
5048
6459
|
events
|
|
5049
6460
|
.sort((event1, event2) => event1.path.length - event2.path.length);
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
6461
|
+
fs.push(() => {
|
|
6462
|
+
// We don't need to check for events.length
|
|
6463
|
+
// because we know it has at least one element
|
|
6464
|
+
callEventHandlerListeners(type._dEH, events, transaction);
|
|
6465
|
+
});
|
|
6466
|
+
}
|
|
6467
|
+
});
|
|
6468
|
+
fs.push(() => doc.emit('afterTransaction', [transaction, doc]));
|
|
6469
|
+
fs.push(() => {
|
|
6470
|
+
if (transaction._needFormattingCleanup) {
|
|
6471
|
+
cleanupYTextAfterTransaction(transaction);
|
|
5053
6472
|
}
|
|
5054
6473
|
});
|
|
5055
6474
|
});
|
|
5056
|
-
fs.push(() => doc.emit('afterTransaction', [transaction, doc]));
|
|
5057
6475
|
callAll(fs, []);
|
|
5058
|
-
if (transaction._needFormattingCleanup) {
|
|
5059
|
-
cleanupYTextAfterTransaction(transaction);
|
|
5060
|
-
}
|
|
5061
6476
|
} finally {
|
|
5062
6477
|
// Replace deleted items with ItemDeleted / GC.
|
|
5063
6478
|
// This is where content is actually remove from the Yjs Doc.
|
|
@@ -5619,7 +7034,7 @@ class YEvent {
|
|
|
5619
7034
|
*/
|
|
5620
7035
|
this._changes = null;
|
|
5621
7036
|
/**
|
|
5622
|
-
* @type {null | Map<string, { action: 'add' | 'update' | 'delete', oldValue: any
|
|
7037
|
+
* @type {null | Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>}
|
|
5623
7038
|
*/
|
|
5624
7039
|
this._keys = null;
|
|
5625
7040
|
/**
|
|
@@ -5662,7 +7077,7 @@ class YEvent {
|
|
|
5662
7077
|
}
|
|
5663
7078
|
|
|
5664
7079
|
/**
|
|
5665
|
-
* @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any
|
|
7080
|
+
* @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>}
|
|
5666
7081
|
*/
|
|
5667
7082
|
get keys () {
|
|
5668
7083
|
if (this._keys === null) {
|
|
@@ -9037,12 +10452,10 @@ class YXmlElement extends YXmlFragment {
|
|
|
9037
10452
|
const el = new YXmlElement(this.nodeName);
|
|
9038
10453
|
const attrs = this.getAttributes();
|
|
9039
10454
|
forEach$2(attrs, (value, key) => {
|
|
9040
|
-
|
|
9041
|
-
el.setAttribute(key, value);
|
|
9042
|
-
}
|
|
10455
|
+
el.setAttribute(key, /** @type {any} */ (value));
|
|
9043
10456
|
});
|
|
9044
10457
|
// @ts-ignore
|
|
9045
|
-
el.insert(0, this.toArray().map(
|
|
10458
|
+
el.insert(0, this.toArray().map(v => v instanceof AbstractType ? v.clone() : v));
|
|
9046
10459
|
return el
|
|
9047
10460
|
}
|
|
9048
10461
|
|
|
@@ -11340,6 +12753,8 @@ class KokimokiAiService {
|
|
|
11340
12753
|
* higher values make it more creative and varied.
|
|
11341
12754
|
* @param req.maxTokens Optional. The maximum number of tokens to generate in the response.
|
|
11342
12755
|
* Controls the length of the AI's output.
|
|
12756
|
+
* @param req.imageUrls Optional. Image URLs to include with the user prompt (Gemini models only).
|
|
12757
|
+
* Allows the AI to analyze and respond based on the provided images.
|
|
11343
12758
|
*
|
|
11344
12759
|
* @returns A promise that resolves to an object containing the AI-generated response.
|
|
11345
12760
|
* @returns {string} content The text content of the AI's response.
|
|
@@ -11434,6 +12849,330 @@ class KokimokiAiService {
|
|
|
11434
12849
|
}
|
|
11435
12850
|
}
|
|
11436
12851
|
|
|
12852
|
+
let _kmEnv;
|
|
12853
|
+
/**
|
|
12854
|
+
* Parses and returns the Kokimoki environment configuration.
|
|
12855
|
+
*
|
|
12856
|
+
* The environment is injected into the HTML by @kokimoki/kit as a JSON script tag
|
|
12857
|
+
* with id `kokimoki-env`. In production, placeholder values are replaced by the server.
|
|
12858
|
+
*
|
|
12859
|
+
* @returns The parsed KokimokiEnv object
|
|
12860
|
+
* @throws Error if the kokimoki-env element is not found
|
|
12861
|
+
*
|
|
12862
|
+
* @example
|
|
12863
|
+
* ```typescript
|
|
12864
|
+
* import { getKmEnv } from '@kokimoki/app';
|
|
12865
|
+
*
|
|
12866
|
+
* const env = getKmEnv();
|
|
12867
|
+
* console.log(env.dev); // true in development
|
|
12868
|
+
* console.log(env.assets); // CDN URL in production
|
|
12869
|
+
*
|
|
12870
|
+
* // Cast i18n to your app's type if needed
|
|
12871
|
+
* const i18n = env.i18n as typeof i18nResources;
|
|
12872
|
+
* ```
|
|
12873
|
+
*/
|
|
12874
|
+
function getKmEnv() {
|
|
12875
|
+
if (_kmEnv) {
|
|
12876
|
+
return _kmEnv;
|
|
12877
|
+
}
|
|
12878
|
+
const element = document.getElementById("kokimoki-env");
|
|
12879
|
+
if (!element) {
|
|
12880
|
+
throw new Error("kokimoki-env element not found. Ensure the app is built with @kokimoki/kit.");
|
|
12881
|
+
}
|
|
12882
|
+
_kmEnv = JSON.parse(element.textContent);
|
|
12883
|
+
return _kmEnv;
|
|
12884
|
+
}
|
|
12885
|
+
|
|
12886
|
+
/**
|
|
12887
|
+
* Kokimoki i18n Service
|
|
12888
|
+
*
|
|
12889
|
+
* Provides translation loading via HTTP backend. Both development and production
|
|
12890
|
+
* use HTTP to load translations consistently.
|
|
12891
|
+
*
|
|
12892
|
+
* In development, translations are served by @kokimoki/kit's dev server middleware.
|
|
12893
|
+
* In production, translations are served from the assets CDN.
|
|
12894
|
+
*
|
|
12895
|
+
* **Key Features:**
|
|
12896
|
+
* - Pre-configured i18next instance creation
|
|
12897
|
+
* - Consistent HTTP-based loading in dev and prod
|
|
12898
|
+
* - URL resolution for translation namespaces
|
|
12899
|
+
* - AI-powered translation requests
|
|
12900
|
+
*
|
|
12901
|
+
* Access via `kmClient.i18n`
|
|
12902
|
+
*
|
|
12903
|
+
* @example
|
|
12904
|
+
* ```typescript
|
|
12905
|
+
* // Setup with React
|
|
12906
|
+
* import { initReactI18next } from 'react-i18next';
|
|
12907
|
+
*
|
|
12908
|
+
* export const i18n = kmClient.i18n.createI18n({
|
|
12909
|
+
* use: [initReactI18next]
|
|
12910
|
+
* });
|
|
12911
|
+
*
|
|
12912
|
+
* // Initialize with primary language
|
|
12913
|
+
* await kmClient.i18n.init('en');
|
|
12914
|
+
*
|
|
12915
|
+
* // Request AI translation for another language
|
|
12916
|
+
* const result = await kmClient.i18n.requestTranslation('de');
|
|
12917
|
+
* // Then poll getTranslationStatus('de') until available
|
|
12918
|
+
* ```
|
|
12919
|
+
*/
|
|
12920
|
+
class KokimokiI18nService {
|
|
12921
|
+
client;
|
|
12922
|
+
initPromise = null;
|
|
12923
|
+
instance = null;
|
|
12924
|
+
options = {};
|
|
12925
|
+
constructor(client) {
|
|
12926
|
+
this.client = client;
|
|
12927
|
+
}
|
|
12928
|
+
/**
|
|
12929
|
+
* Create and configure an i18next instance.
|
|
12930
|
+
*
|
|
12931
|
+
* This sets up the instance with plugins but does NOT initialize it.
|
|
12932
|
+
* Call `init(lng)` to initialize with a specific language.
|
|
12933
|
+
*
|
|
12934
|
+
* @param options - Configuration options (plugins, fallback, defaultNS)
|
|
12935
|
+
* @returns Configured i18next instance (not yet initialized)
|
|
12936
|
+
*
|
|
12937
|
+
* @example
|
|
12938
|
+
* ```typescript
|
|
12939
|
+
* // With React
|
|
12940
|
+
* import { initReactI18next } from 'react-i18next';
|
|
12941
|
+
*
|
|
12942
|
+
* export const i18n = kmClient.i18n.createI18n({
|
|
12943
|
+
* use: [initReactI18next]
|
|
12944
|
+
* });
|
|
12945
|
+
*
|
|
12946
|
+
* // Later, when you know the language:
|
|
12947
|
+
* await kmClient.i18n.init('en');
|
|
12948
|
+
*
|
|
12949
|
+
* // Then in components:
|
|
12950
|
+
* const { t } = useTranslation('game');
|
|
12951
|
+
* ```
|
|
12952
|
+
*/
|
|
12953
|
+
createI18n(options) {
|
|
12954
|
+
const env = getKmEnv();
|
|
12955
|
+
const namespaces = env.i18nNamespaces ?? [];
|
|
12956
|
+
if (namespaces.length === 0) {
|
|
12957
|
+
console.warn("[KokimokiI18n] No i18n namespaces found. Make sure i18n is configured in @kokimoki/kit plugin.");
|
|
12958
|
+
}
|
|
12959
|
+
this.options = options ?? {};
|
|
12960
|
+
this.instance = i18next.createInstance();
|
|
12961
|
+
// Apply plugins
|
|
12962
|
+
if (options?.use) {
|
|
12963
|
+
for (const plugin of options.use) {
|
|
12964
|
+
this.instance.use(plugin);
|
|
12965
|
+
}
|
|
12966
|
+
}
|
|
12967
|
+
// Add HTTP backend
|
|
12968
|
+
this.instance.use(HttpBackend);
|
|
12969
|
+
return this.instance;
|
|
12970
|
+
}
|
|
12971
|
+
/**
|
|
12972
|
+
* Initialize the i18next instance with a specific language.
|
|
12973
|
+
*
|
|
12974
|
+
* Must call `createI18n()` first to set up the instance.
|
|
12975
|
+
*
|
|
12976
|
+
* @param lng - The language code to initialize with (e.g., 'en', 'de')
|
|
12977
|
+
* @returns Promise that resolves when i18n is ready
|
|
12978
|
+
*
|
|
12979
|
+
* @example
|
|
12980
|
+
* ```typescript
|
|
12981
|
+
* // Create instance first
|
|
12982
|
+
* const i18n = kmClient.i18n.createI18n({ use: [initReactI18next] });
|
|
12983
|
+
*
|
|
12984
|
+
* // Then initialize when you know the language
|
|
12985
|
+
* await kmClient.i18n.init('en');
|
|
12986
|
+
* ```
|
|
12987
|
+
*/
|
|
12988
|
+
async init(lng) {
|
|
12989
|
+
if (!this.instance) {
|
|
12990
|
+
throw new Error("Call createI18n() before init()");
|
|
12991
|
+
}
|
|
12992
|
+
if (this.initPromise) {
|
|
12993
|
+
return this.initPromise;
|
|
12994
|
+
}
|
|
12995
|
+
const env = getKmEnv();
|
|
12996
|
+
const namespaces = env.i18nNamespaces ?? [];
|
|
12997
|
+
const fallbackLng = this.options.fallbackLng ?? lng;
|
|
12998
|
+
const defaultNS = this.options.defaultNS;
|
|
12999
|
+
this.initPromise = this.instance.init({
|
|
13000
|
+
lng,
|
|
13001
|
+
fallbackLng,
|
|
13002
|
+
ns: namespaces,
|
|
13003
|
+
defaultNS,
|
|
13004
|
+
backend: {
|
|
13005
|
+
loadPath: (lng, ns) => this.getNamespaceUrl(lng, ns),
|
|
13006
|
+
},
|
|
13007
|
+
interpolation: {
|
|
13008
|
+
escapeValue: false,
|
|
13009
|
+
},
|
|
13010
|
+
});
|
|
13011
|
+
return this.initPromise;
|
|
13012
|
+
}
|
|
13013
|
+
/**
|
|
13014
|
+
* Get the URL for a translation namespace.
|
|
13015
|
+
*
|
|
13016
|
+
* Returns the appropriate URL based on environment:
|
|
13017
|
+
* - Development: `/__kokimoki/i18n/{lng}/{ns}.json`
|
|
13018
|
+
* - Production: `{assets}/km-i18n/{lng}/{ns}.json`
|
|
13019
|
+
*
|
|
13020
|
+
* @param lng - Language code (e.g., 'en', 'et', 'de')
|
|
13021
|
+
* @param ns - Namespace (e.g., 'ui', 'game', 'setup')
|
|
13022
|
+
* @returns Full URL to the translation JSON file
|
|
13023
|
+
*
|
|
13024
|
+
* @example
|
|
13025
|
+
* ```typescript
|
|
13026
|
+
* const url = kmClient.i18n.getNamespaceUrl('en', 'game');
|
|
13027
|
+
* // Dev: "/__kokimoki/i18n/en/game.json"
|
|
13028
|
+
* // Prod: "https://cdn.kokimoki.com/build-123/km-i18n/en/game.json"
|
|
13029
|
+
* ```
|
|
13030
|
+
*/
|
|
13031
|
+
getNamespaceUrl(lng, ns) {
|
|
13032
|
+
const env = getKmEnv();
|
|
13033
|
+
if (env.dev) {
|
|
13034
|
+
// Development: use kit plugin's middleware
|
|
13035
|
+
return `/__kokimoki/i18n/${lng}/${ns}.json`;
|
|
13036
|
+
}
|
|
13037
|
+
// Production: use assets CDN with configured i18n path
|
|
13038
|
+
const i18nPath = env.i18nPath ?? 'km-i18n';
|
|
13039
|
+
return `${env.assets}/${i18nPath}/${lng}/${ns}.json`;
|
|
13040
|
+
}
|
|
13041
|
+
/**
|
|
13042
|
+
* Get the list of available namespaces.
|
|
13043
|
+
*
|
|
13044
|
+
* @returns Array of namespace names configured in @kokimoki/kit
|
|
13045
|
+
*/
|
|
13046
|
+
getNamespaces() {
|
|
13047
|
+
return getKmEnv().i18nNamespaces ?? [];
|
|
13048
|
+
}
|
|
13049
|
+
/**
|
|
13050
|
+
* Get the list of available languages.
|
|
13051
|
+
*
|
|
13052
|
+
* @returns Array of language codes configured in @kokimoki/kit
|
|
13053
|
+
*/
|
|
13054
|
+
getLanguages() {
|
|
13055
|
+
return getKmEnv().i18nLanguages ?? [];
|
|
13056
|
+
}
|
|
13057
|
+
/**
|
|
13058
|
+
* Get the status of all languages that have been requested for AI translation.
|
|
13059
|
+
*
|
|
13060
|
+
* Only available in production. In development, returns an empty array.
|
|
13061
|
+
*
|
|
13062
|
+
* @returns Promise with array of language statuses
|
|
13063
|
+
*
|
|
13064
|
+
* @example
|
|
13065
|
+
* ```typescript
|
|
13066
|
+
* const { languages } = await kmClient.i18n.getAllLanguagesStatus();
|
|
13067
|
+
* // [{ lng: 'de', status: 'available' }, { lng: 'fr', status: 'processing' }]
|
|
13068
|
+
* ```
|
|
13069
|
+
*/
|
|
13070
|
+
async getAllLanguagesStatus() {
|
|
13071
|
+
const env = getKmEnv();
|
|
13072
|
+
if (env.dev) {
|
|
13073
|
+
return { languages: [] };
|
|
13074
|
+
}
|
|
13075
|
+
const res = await fetch(`${this.client.apiUrl}/i18n`, {
|
|
13076
|
+
method: "GET",
|
|
13077
|
+
headers: this.client.apiHeaders,
|
|
13078
|
+
});
|
|
13079
|
+
return await res.json();
|
|
13080
|
+
}
|
|
13081
|
+
/**
|
|
13082
|
+
* Get the translation status for a specific language.
|
|
13083
|
+
*
|
|
13084
|
+
* Returns the overall status and per-namespace status for the given language.
|
|
13085
|
+
* In development, returns 'available' for local languages and 'not_available' for others.
|
|
13086
|
+
* In production, queries the API for the actual status.
|
|
13087
|
+
*
|
|
13088
|
+
* @param lng - Target language code (e.g., 'de', 'fr', 'es')
|
|
13089
|
+
* @returns Promise with translation status
|
|
13090
|
+
*
|
|
13091
|
+
* @example
|
|
13092
|
+
* ```typescript
|
|
13093
|
+
* const status = await kmClient.i18n.getTranslationStatus('de');
|
|
13094
|
+
* if (status.status === 'available') {
|
|
13095
|
+
* // All translations ready, can switch language
|
|
13096
|
+
* i18next.changeLanguage('de');
|
|
13097
|
+
* } else if (status.status === 'processing') {
|
|
13098
|
+
* // Show loading indicator
|
|
13099
|
+
* } else {
|
|
13100
|
+
* // Request translation
|
|
13101
|
+
* await kmClient.i18n.requestTranslation('de');
|
|
13102
|
+
* }
|
|
13103
|
+
* ```
|
|
13104
|
+
*/
|
|
13105
|
+
async getTranslationStatus(lng) {
|
|
13106
|
+
const env = getKmEnv();
|
|
13107
|
+
if (env.dev) {
|
|
13108
|
+
// In dev, only local languages are available
|
|
13109
|
+
const localLanguages = this.getLanguages();
|
|
13110
|
+
const namespaces = this.getNamespaces();
|
|
13111
|
+
const isLocal = localLanguages.includes(lng);
|
|
13112
|
+
const status = isLocal ? "available" : "not_available";
|
|
13113
|
+
return {
|
|
13114
|
+
status,
|
|
13115
|
+
namespaces: Object.fromEntries(namespaces.map((ns) => [ns, status])),
|
|
13116
|
+
};
|
|
13117
|
+
}
|
|
13118
|
+
const res = await fetch(`${this.client.apiUrl}/i18n/${encodeURIComponent(lng)}/status`, {
|
|
13119
|
+
method: "GET",
|
|
13120
|
+
headers: this.client.apiHeaders,
|
|
13121
|
+
});
|
|
13122
|
+
return await res.json();
|
|
13123
|
+
}
|
|
13124
|
+
/**
|
|
13125
|
+
* Request AI translation for a target language.
|
|
13126
|
+
*
|
|
13127
|
+
* Triggers background AI translation jobs for all namespaces that are not yet available.
|
|
13128
|
+
* Uses the build's configured primary language as the source.
|
|
13129
|
+
*
|
|
13130
|
+
* In development, returns 'already_available' for local languages and throws an error for others.
|
|
13131
|
+
* In production, triggers the API to start translation.
|
|
13132
|
+
*
|
|
13133
|
+
* @param lng - Target language code (e.g., 'de', 'fr', 'es')
|
|
13134
|
+
* @returns Promise with the result of the request
|
|
13135
|
+
*
|
|
13136
|
+
* @example
|
|
13137
|
+
* ```typescript
|
|
13138
|
+
* const result = await kmClient.i18n.requestTranslation('de');
|
|
13139
|
+
*
|
|
13140
|
+
* if (result.status === 'started') {
|
|
13141
|
+
* // Translation started, poll for status
|
|
13142
|
+
* const checkStatus = async () => {
|
|
13143
|
+
* const status = await kmClient.i18n.getTranslationStatus('de');
|
|
13144
|
+
* if (status.status === 'available') {
|
|
13145
|
+
* i18next.changeLanguage('de');
|
|
13146
|
+
* } else if (status.status === 'processing') {
|
|
13147
|
+
* setTimeout(checkStatus, 2000);
|
|
13148
|
+
* }
|
|
13149
|
+
* };
|
|
13150
|
+
* checkStatus();
|
|
13151
|
+
* } else if (result.status === 'already_available') {
|
|
13152
|
+
* // Already translated, switch immediately
|
|
13153
|
+
* i18next.changeLanguage('de');
|
|
13154
|
+
* }
|
|
13155
|
+
* ```
|
|
13156
|
+
*/
|
|
13157
|
+
async requestTranslation(lng) {
|
|
13158
|
+
const env = getKmEnv();
|
|
13159
|
+
if (env.dev) {
|
|
13160
|
+
// In dev, only local languages are available
|
|
13161
|
+
const localLanguages = this.getLanguages();
|
|
13162
|
+
if (localLanguages.includes(lng)) {
|
|
13163
|
+
return { status: "already_available" };
|
|
13164
|
+
}
|
|
13165
|
+
// AI translation not available in dev mode
|
|
13166
|
+
throw new Error(`AI translation not available in dev mode. Add local translations for '${lng}' in src/i18n/${lng}/`);
|
|
13167
|
+
}
|
|
13168
|
+
const res = await fetch(`${this.client.apiUrl}/i18n/${encodeURIComponent(lng)}/translate`, {
|
|
13169
|
+
method: "POST",
|
|
13170
|
+
headers: this.client.apiHeaders,
|
|
13171
|
+
});
|
|
13172
|
+
return await res.json();
|
|
13173
|
+
}
|
|
13174
|
+
}
|
|
13175
|
+
|
|
11437
13176
|
/**
|
|
11438
13177
|
* Kokimoki Leaderboard Service
|
|
11439
13178
|
*
|
|
@@ -15045,7 +16784,7 @@ const createHandlerDefault = (isInitializing, addPropListener, removePropListene
|
|
|
15045
16784
|
removePropListener(prop);
|
|
15046
16785
|
const deleted = Reflect.deleteProperty(target, prop);
|
|
15047
16786
|
if (deleted) {
|
|
15048
|
-
notifyUpdate(
|
|
16787
|
+
notifyUpdate(createOp == null ? void 0 : createOp("delete", prop, prevValue));
|
|
15049
16788
|
}
|
|
15050
16789
|
return deleted;
|
|
15051
16790
|
},
|
|
@@ -15062,10 +16801,11 @@ const createHandlerDefault = (isInitializing, addPropListener, removePropListene
|
|
|
15062
16801
|
const nextValue = !proxyStateMap.has(value) && canProxy(value) ? proxy(value) : value;
|
|
15063
16802
|
addPropListener(prop, nextValue);
|
|
15064
16803
|
Reflect.set(target, prop, nextValue, receiver);
|
|
15065
|
-
notifyUpdate(
|
|
16804
|
+
notifyUpdate(createOp == null ? void 0 : createOp("set", prop, value, prevValue));
|
|
15066
16805
|
return true;
|
|
15067
16806
|
}
|
|
15068
16807
|
});
|
|
16808
|
+
const createOpDefault = (type, prop, ...args) => [type, [prop], ...args];
|
|
15069
16809
|
const proxyStateMap = /* @__PURE__ */ new WeakMap();
|
|
15070
16810
|
const refSet = /* @__PURE__ */ new WeakSet();
|
|
15071
16811
|
const snapCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -15076,6 +16816,7 @@ let newProxy = (target, handler) => new Proxy(target, handler);
|
|
|
15076
16816
|
let canProxy = canProxyDefault;
|
|
15077
16817
|
let createSnapshot = createSnapshotDefault;
|
|
15078
16818
|
let createHandler = createHandlerDefault;
|
|
16819
|
+
let createOp;
|
|
15079
16820
|
function proxy(baseObject = {}) {
|
|
15080
16821
|
if (!isObject(baseObject)) {
|
|
15081
16822
|
throw new Error("object required");
|
|
@@ -15106,8 +16847,11 @@ function proxy(baseObject = {}) {
|
|
|
15106
16847
|
return version;
|
|
15107
16848
|
};
|
|
15108
16849
|
const createPropListener = (prop) => (op, nextVersion) => {
|
|
15109
|
-
|
|
15110
|
-
|
|
16850
|
+
let newOp;
|
|
16851
|
+
if (op) {
|
|
16852
|
+
newOp = [...op];
|
|
16853
|
+
newOp[1] = [prop, ...newOp[1]];
|
|
16854
|
+
}
|
|
15111
16855
|
notifyUpdate(newOp, nextVersion);
|
|
15112
16856
|
};
|
|
15113
16857
|
const propProxyStates = /* @__PURE__ */ new Map();
|
|
@@ -15194,7 +16938,9 @@ function subscribe(proxyObject, callback, notifyInSync) {
|
|
|
15194
16938
|
const addListener = proxyState[2];
|
|
15195
16939
|
let isListenerActive = false;
|
|
15196
16940
|
const listener = (op) => {
|
|
15197
|
-
|
|
16941
|
+
if (op) {
|
|
16942
|
+
ops.push(op);
|
|
16943
|
+
}
|
|
15198
16944
|
if (notifyInSync) {
|
|
15199
16945
|
callback(ops.splice(0));
|
|
15200
16946
|
return;
|
|
@@ -15227,6 +16973,15 @@ function ref(obj) {
|
|
|
15227
16973
|
refSet.add(obj);
|
|
15228
16974
|
return obj;
|
|
15229
16975
|
}
|
|
16976
|
+
function unstable_enableOp(enabled = true) {
|
|
16977
|
+
if (enabled === true) {
|
|
16978
|
+
createOp = createOpDefault;
|
|
16979
|
+
} else if (enabled === false) {
|
|
16980
|
+
createOp = void 0;
|
|
16981
|
+
} else {
|
|
16982
|
+
createOp = enabled;
|
|
16983
|
+
}
|
|
16984
|
+
}
|
|
15230
16985
|
|
|
15231
16986
|
const parseProxyOps = (ops) => {
|
|
15232
16987
|
const indexed = new Set();
|
|
@@ -15959,7 +17714,7 @@ class KokimokiTransaction {
|
|
|
15959
17714
|
}
|
|
15960
17715
|
|
|
15961
17716
|
// Auto-generated file. Do not edit manually.
|
|
15962
|
-
const KOKIMOKI_APP_VERSION = '2.1.
|
|
17717
|
+
const KOKIMOKI_APP_VERSION = '2.1.1';
|
|
15963
17718
|
|
|
15964
17719
|
var RoomSubscriptionMode;
|
|
15965
17720
|
(function (RoomSubscriptionMode) {
|
|
@@ -16200,6 +17955,7 @@ class KokimokiClient extends EventEmitter$1 {
|
|
|
16200
17955
|
_clientTokenKey = "KM_TOKEN";
|
|
16201
17956
|
_editorContext;
|
|
16202
17957
|
_ai;
|
|
17958
|
+
_i18n;
|
|
16203
17959
|
_storage;
|
|
16204
17960
|
_leaderboard;
|
|
16205
17961
|
constructor(host, appId, code = "") {
|
|
@@ -16213,6 +17969,7 @@ class KokimokiClient extends EventEmitter$1 {
|
|
|
16213
17969
|
this._apiUrl = `http${secure ? "s" : ""}://${this.host}`;
|
|
16214
17970
|
// Initialize modules
|
|
16215
17971
|
this._ai = new KokimokiAiService(this);
|
|
17972
|
+
this._i18n = new KokimokiI18nService(this);
|
|
16216
17973
|
this._storage = new KokimokiStorageService(this);
|
|
16217
17974
|
this._leaderboard = new KokimokiLeaderboardService(this);
|
|
16218
17975
|
// Set up ping interval
|
|
@@ -16722,6 +18479,44 @@ class KokimokiClient extends EventEmitter$1 {
|
|
|
16722
18479
|
clearInterval(this._pingInterval);
|
|
16723
18480
|
}
|
|
16724
18481
|
}
|
|
18482
|
+
/**
|
|
18483
|
+
* Waits for all subscriptions to be fully joined.
|
|
18484
|
+
*
|
|
18485
|
+
* This is useful when you need to ensure all stores have completed their initial
|
|
18486
|
+
* synchronization before proceeding (e.g., before running tests or taking snapshots).
|
|
18487
|
+
*
|
|
18488
|
+
* @param timeout - Maximum time to wait in milliseconds (default: 5000ms).
|
|
18489
|
+
* @returns A promise that resolves when all subscriptions are joined, or when timeout is reached.
|
|
18490
|
+
*
|
|
18491
|
+
* @example
|
|
18492
|
+
* ```ts
|
|
18493
|
+
* // Wait for all stores to sync before starting game
|
|
18494
|
+
* await client.waitForSubscriptions();
|
|
18495
|
+
*
|
|
18496
|
+
* // Wait with custom timeout
|
|
18497
|
+
* await client.waitForSubscriptions(10000);
|
|
18498
|
+
* ```
|
|
18499
|
+
*/
|
|
18500
|
+
async waitForSubscriptions(timeout = 5000) {
|
|
18501
|
+
const checkInterval = 10;
|
|
18502
|
+
const maxChecks = Math.ceil(timeout / checkInterval);
|
|
18503
|
+
return new Promise((resolve) => {
|
|
18504
|
+
let checks = 0;
|
|
18505
|
+
const intervalId = setInterval(() => {
|
|
18506
|
+
let allJoined = true;
|
|
18507
|
+
for (const subscription of this._subscriptionsByName.values()) {
|
|
18508
|
+
if (!subscription.joined) {
|
|
18509
|
+
allJoined = false;
|
|
18510
|
+
break;
|
|
18511
|
+
}
|
|
18512
|
+
}
|
|
18513
|
+
if (allJoined || ++checks >= maxChecks) {
|
|
18514
|
+
clearInterval(intervalId);
|
|
18515
|
+
resolve();
|
|
18516
|
+
}
|
|
18517
|
+
}, checkInterval);
|
|
18518
|
+
});
|
|
18519
|
+
}
|
|
16725
18520
|
/**
|
|
16726
18521
|
* Gets the internal room hash identifier for a store.
|
|
16727
18522
|
*
|
|
@@ -16813,6 +18608,15 @@ class KokimokiClient extends EventEmitter$1 {
|
|
|
16813
18608
|
}
|
|
16814
18609
|
return this._ai;
|
|
16815
18610
|
}
|
|
18611
|
+
/**
|
|
18612
|
+
* Access i18n URL resolution and translation loading utilities.
|
|
18613
|
+
*/
|
|
18614
|
+
get i18n() {
|
|
18615
|
+
if (!this._i18n) {
|
|
18616
|
+
throw new Error("I18n client not initialized");
|
|
18617
|
+
}
|
|
18618
|
+
return this._i18n;
|
|
18619
|
+
}
|
|
16816
18620
|
/**
|
|
16817
18621
|
* Access file upload and management for media files, images, and user-generated content.
|
|
16818
18622
|
*/
|
|
@@ -17143,7 +18947,14 @@ function subscribeKey(proxyObject, key, callback, notifyInSync) {
|
|
|
17143
18947
|
}
|
|
17144
18948
|
|
|
17145
18949
|
let currentCleanups;
|
|
18950
|
+
let didWarnDeprecation = false;
|
|
17146
18951
|
function watch(callback, options) {
|
|
18952
|
+
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !didWarnDeprecation) {
|
|
18953
|
+
console.warn(
|
|
18954
|
+
"[DEPRECATED] The `watch` util is no longer maintained. Please migrate to [valtio-reactive](https://github.com/valtiojs/valtio-reactive)."
|
|
18955
|
+
);
|
|
18956
|
+
didWarnDeprecation = true;
|
|
18957
|
+
}
|
|
17147
18958
|
let alive = true;
|
|
17148
18959
|
const cleanups = /* @__PURE__ */ new Set();
|
|
17149
18960
|
const subscriptions = /* @__PURE__ */ new Map();
|
|
@@ -17199,7 +19010,7 @@ function watch(callback, options) {
|
|
|
17199
19010
|
return cleanup;
|
|
17200
19011
|
}
|
|
17201
19012
|
|
|
17202
|
-
const DEVTOOLS = Symbol();
|
|
19013
|
+
const DEVTOOLS = /* @__PURE__ */ Symbol();
|
|
17203
19014
|
function devtools(proxyObject, options) {
|
|
17204
19015
|
const { enabled, name = "", ...rest } = options || {};
|
|
17205
19016
|
let extension;
|
|
@@ -17213,10 +19024,11 @@ function devtools(proxyObject, options) {
|
|
|
17213
19024
|
}
|
|
17214
19025
|
return;
|
|
17215
19026
|
}
|
|
19027
|
+
unstable_enableOp();
|
|
17216
19028
|
let isTimeTraveling = false;
|
|
17217
19029
|
const devtools2 = extension.connect({ name, ...rest });
|
|
17218
|
-
const unsub1 = subscribe(proxyObject, (
|
|
17219
|
-
const action =
|
|
19030
|
+
const unsub1 = subscribe(proxyObject, (unstable_ops) => {
|
|
19031
|
+
const action = unstable_ops.filter(([_, path]) => path[0] !== DEVTOOLS).map(([op, path]) => `${op}:${path.map(String).join(".")}`).join(", ");
|
|
17220
19032
|
if (!action) {
|
|
17221
19033
|
return;
|
|
17222
19034
|
}
|
|
@@ -17277,7 +19089,7 @@ function devtools(proxyObject, options) {
|
|
|
17277
19089
|
};
|
|
17278
19090
|
}
|
|
17279
19091
|
|
|
17280
|
-
const DUMMY_SYMBOL = Symbol();
|
|
19092
|
+
const DUMMY_SYMBOL = /* @__PURE__ */ Symbol();
|
|
17281
19093
|
function useProxy(proxy, options) {
|
|
17282
19094
|
const snapshot = useSnapshot(proxy, options);
|
|
17283
19095
|
snapshot[DUMMY_SYMBOL];
|
|
@@ -17292,5 +19104,5 @@ function useProxy(proxy, options) {
|
|
|
17292
19104
|
});
|
|
17293
19105
|
}
|
|
17294
19106
|
|
|
17295
|
-
export { KokimokiClient, KokimokiStore, derive, devtools, proxy, ref, snapshot, subscribe, subscribeKey, underive, useProxy, useSnapshot, watch };
|
|
19107
|
+
export { KokimokiClient, KokimokiStore, derive, devtools, getKmEnv, proxy, ref, snapshot, subscribe, subscribeKey, underive, useProxy, useSnapshot, watch };
|
|
17296
19108
|
//# sourceMappingURL=kokimoki.min.js.map
|