@rb-games/core 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/chunk-5BLUF2HG.js +25 -0
  2. package/dist/chunk-5BLUF2HG.js.map +1 -0
  3. package/dist/chunk-DOHQE2YZ.js +392 -0
  4. package/dist/chunk-DOHQE2YZ.js.map +1 -0
  5. package/dist/chunk-FOZO6TLY.js +673 -0
  6. package/dist/chunk-FOZO6TLY.js.map +1 -0
  7. package/dist/chunk-G3PMV62Z.js +33 -0
  8. package/dist/chunk-G3PMV62Z.js.map +1 -0
  9. package/dist/chunk-JHN6RF66.js +1580 -0
  10. package/dist/chunk-JHN6RF66.js.map +1 -0
  11. package/dist/chunk-MI6BP7A6.js +11 -0
  12. package/dist/chunk-MI6BP7A6.js.map +1 -0
  13. package/dist/chunk-NAQG7TMS.js +5517 -0
  14. package/dist/chunk-NAQG7TMS.js.map +1 -0
  15. package/dist/chunk-NQMORMNP.js +15 -0
  16. package/dist/chunk-NQMORMNP.js.map +1 -0
  17. package/dist/chunk-RAEOBW6E.js +133 -0
  18. package/dist/chunk-RAEOBW6E.js.map +1 -0
  19. package/dist/chunk-UE7T7Z45.js +884 -0
  20. package/dist/chunk-UE7T7Z45.js.map +1 -0
  21. package/dist/chunk-YSLGJAV6.js +492 -0
  22. package/dist/chunk-YSLGJAV6.js.map +1 -0
  23. package/dist/devtools/index.js +2 -882
  24. package/dist/devtools/index.js.map +1 -1
  25. package/dist/engine/index.js +6 -1267
  26. package/dist/engine/index.js.map +1 -1
  27. package/dist/filters/index.js +1 -1
  28. package/dist/helpers/index.js +13 -39
  29. package/dist/helpers/index.js.map +1 -1
  30. package/dist/i18n/index.js +4 -525
  31. package/dist/i18n/index.js.map +1 -1
  32. package/dist/layout/index.js +2 -671
  33. package/dist/layout/index.js.map +1 -1
  34. package/dist/particle/index.js +1 -6
  35. package/dist/particle/index.js.map +1 -1
  36. package/dist/plugins/Plugin.types.d.ts +4 -2
  37. package/dist/plugins/Plugin.types.d.ts.map +1 -1
  38. package/dist/plugins/index.js +11 -523
  39. package/dist/plugins/index.js.map +1 -1
  40. package/dist/state-machine/index.js +4 -2
  41. package/dist/state-machine/index.js.map +1 -1
  42. package/dist/store/index.js +1 -1
  43. package/dist/ui/index.js +28 -536
  44. package/dist/ui/index.js.map +1 -1
  45. package/dist/utils/index.js +5 -897
  46. package/dist/utils/index.js.map +1 -1
  47. package/dist/vite/index.js +4 -2
  48. package/dist/vite/index.js.map +1 -1
  49. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ // helpers/resolvePublicPath.ts
2
+ function resolvePublicPath(path) {
3
+ var _a;
4
+ if (path.startsWith("http://") || path.startsWith("https://")) {
5
+ return path;
6
+ }
7
+ const base = typeof import.meta !== "undefined" && ((_a = import.meta.env) == null ? void 0 : _a.BASE_URL) ? import.meta.env.BASE_URL : "/";
8
+ const normalizedBase = base.endsWith("/") ? base : `${base}/`;
9
+ const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
10
+ return `${normalizedBase}${normalizedPath}`;
11
+ }
12
+
13
+ export { resolvePublicPath };
14
+ //# sourceMappingURL=chunk-NQMORMNP.js.map
15
+ //# sourceMappingURL=chunk-NQMORMNP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../helpers/resolvePublicPath.ts"],"names":[],"mappings":";AAIO,SAAS,kBAAkB,IAAA,EAAsB;AAJxD,EAAA,IAAA,EAAA;AAKE,EAAA,IAAI,KAAK,UAAA,CAAW,SAAS,KAAK,IAAA,CAAK,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GACJ,OAAO,MAAA,CAAA,IAAA,KAAgB,WAAA,KAAA,CAAe,EAAA,GAAA,MAAA,CAAA,IAAA,CAAY,QAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiB,QAAA,CAAA,GACnD,MAAA,CAAA,IAAA,CAAY,GAAA,CAAI,QAAA,GAChB,GAAA;AAEN,EAAA,MAAM,iBAAiB,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,GAAO,GAAG,IAAI,CAAA,CAAA,CAAA;AAC1D,EAAA,MAAM,cAAA,GAAiB,KAAK,UAAA,CAAW,GAAG,IAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AAE9D,EAAA,OAAO,CAAA,EAAG,cAAc,CAAA,EAAG,cAAc,CAAA,CAAA;AAC3C","file":"chunk-NQMORMNP.js","sourcesContent":["/**\n * Resolves a runtime public asset path against Vite's deploy base URL.\n * Use for assets loaded after build (Pixi, i18n, fonts, SVGs, etc.).\n */\nexport function resolvePublicPath(path: string): string {\n if (path.startsWith('http://') || path.startsWith('https://')) {\n return path;\n }\n\n const base =\n typeof import.meta !== 'undefined' && import.meta.env?.BASE_URL\n ? import.meta.env.BASE_URL\n : '/';\n\n const normalizedBase = base.endsWith('/') ? base : `${base}/`;\n const normalizedPath = path.startsWith('/') ? path.slice(1) : path;\n\n return `${normalizedBase}${normalizedPath}`;\n}\n"]}
@@ -0,0 +1,133 @@
1
+ import { resolvePublicPath } from './chunk-NQMORMNP.js';
2
+ import { getLogger } from './chunk-DOHQE2YZ.js';
3
+ import i18next from 'i18next';
4
+ import Backend from 'i18next-http-backend';
5
+ import LanguageDetector from 'i18next-browser-languagedetector';
6
+
7
+ var DEFAULT_LANGUAGE = "en";
8
+ var initPromise = null;
9
+ var languageChangedListeners = /* @__PURE__ */ new Set();
10
+ function normalizeLanguageCode(lng) {
11
+ if (!lng) return DEFAULT_LANGUAGE;
12
+ return lng.trim().toLowerCase().split("-")[0] || DEFAULT_LANGUAGE;
13
+ }
14
+ function resolveLanguageFromUrl(search = window.location.search) {
15
+ const raw = new URLSearchParams(search).get("lng");
16
+ return normalizeLanguageCode(raw);
17
+ }
18
+ function createInterpolationFormat() {
19
+ return (value, format) => {
20
+ if (typeof value === "string") {
21
+ value = value.trim();
22
+ }
23
+ if (format === "optional" && (value === null || value === void 0 || value === "")) {
24
+ return "";
25
+ }
26
+ switch (format) {
27
+ case "percentage":
28
+ if (typeof value === "number" && Number.isNaN(value)) return value;
29
+ return `${Number(value)}%`;
30
+ case "uppercase":
31
+ return (value || "").toString().toLocaleUpperCase();
32
+ case "lowercase":
33
+ return (value || "").toString().toLocaleLowerCase();
34
+ case "firstchar":
35
+ return (value || "").toString().split(/([.?!]+\s*|\n+)/g).map((part) => {
36
+ if (/^[.?!]+/.test(part) || /^\s*$/.test(part)) {
37
+ return part;
38
+ }
39
+ return part.toLocaleLowerCase().replace(
40
+ /^(\s*)(\S)/,
41
+ (_, spaces, firstChar) => spaces + firstChar.toLocaleUpperCase()
42
+ );
43
+ }).join("");
44
+ case "camel":
45
+ return (value || "").toString().split(" ").map((word) => {
46
+ return word.charAt(0).toLocaleUpperCase() + (word || "").slice(1).toLocaleLowerCase();
47
+ }).join(" ");
48
+ default:
49
+ return value;
50
+ }
51
+ };
52
+ }
53
+ async function initSlotI18n() {
54
+ if (i18next.isInitialized) {
55
+ return;
56
+ }
57
+ if (initPromise) {
58
+ return initPromise;
59
+ }
60
+ initPromise = (async () => {
61
+ const requestedLng = resolveLanguageFromUrl();
62
+ await i18next.use(Backend).use(LanguageDetector).use({
63
+ type: "postProcessor",
64
+ name: "trimProcessor",
65
+ process(value) {
66
+ if (typeof value === "string") {
67
+ return value.trim();
68
+ }
69
+ return value;
70
+ }
71
+ }).init({
72
+ lng: requestedLng,
73
+ preload: [DEFAULT_LANGUAGE],
74
+ fallbackLng: [DEFAULT_LANGUAGE],
75
+ load: "currentOnly",
76
+ debug: false,
77
+ detection: {
78
+ order: ["querystring", "localStorage", "cookie", "navigator"],
79
+ lookupQuerystring: "lng",
80
+ caches: ["localStorage", "cookie"]
81
+ },
82
+ backend: {
83
+ loadPath: resolvePublicPath("locales/{{lng}}.json"),
84
+ queryStringParams: { v: "1.0.0" }
85
+ },
86
+ interpolation: {
87
+ escapeValue: false,
88
+ format: createInterpolationFormat()
89
+ },
90
+ postProcess: ["trimProcessor"]
91
+ });
92
+ i18next.on("languageChanged", (lng) => {
93
+ const normalized = normalizeLanguageCode(lng);
94
+ for (const listener of languageChangedListeners) {
95
+ listener(normalized);
96
+ }
97
+ });
98
+ getLogger("SharedI18n").info("i18n initialized", { language: getCurrentLanguage() });
99
+ })();
100
+ try {
101
+ await initPromise;
102
+ } catch (error) {
103
+ initPromise = null;
104
+ getLogger("SharedI18n").error("Failed to initialize i18n", error);
105
+ throw error;
106
+ }
107
+ }
108
+ function t(key, options) {
109
+ return i18next.t(key, options);
110
+ }
111
+ async function changeLanguage(lng) {
112
+ const normalized = normalizeLanguageCode(lng);
113
+ await i18next.changeLanguage(normalized);
114
+ }
115
+ function getCurrentLanguage() {
116
+ return normalizeLanguageCode(i18next.language);
117
+ }
118
+ function isI18nReady() {
119
+ return i18next.isInitialized;
120
+ }
121
+ function onLanguageChanged(listener) {
122
+ languageChangedListeners.add(listener);
123
+ return () => {
124
+ languageChangedListeners.delete(listener);
125
+ };
126
+ }
127
+ function getI18nInstance() {
128
+ return i18next;
129
+ }
130
+
131
+ export { changeLanguage, getCurrentLanguage, getI18nInstance, initSlotI18n, isI18nReady, onLanguageChanged, resolveLanguageFromUrl, t };
132
+ //# sourceMappingURL=chunk-RAEOBW6E.js.map
133
+ //# sourceMappingURL=chunk-RAEOBW6E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../i18n/sharedI18n.ts"],"names":[],"mappings":"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","file":"chunk-RAEOBW6E.js","sourcesContent":["import i18next from 'i18next';\nimport Backend from 'i18next-http-backend';\nimport LanguageDetector from 'i18next-browser-languagedetector';\nimport { resolvePublicPath } from '../helpers/resolvePublicPath';\nimport { getLogger } from '../utils/Logger';\n\nconst DEFAULT_LANGUAGE = 'en';\n\nlet initPromise: Promise<void> | null = null;\nconst languageChangedListeners = new Set<(lng: string) => void>();\n\nfunction normalizeLanguageCode(lng: string | null | undefined): string {\n if (!lng) return DEFAULT_LANGUAGE;\n return lng.trim().toLowerCase().split('-')[0] || DEFAULT_LANGUAGE;\n}\n\n/** Reads `?lng=TR` (case-insensitive) and returns ISO code e.g. `tr`. */\nexport function resolveLanguageFromUrl(search = window.location.search): string {\n const raw = new URLSearchParams(search).get('lng');\n return normalizeLanguageCode(raw);\n}\n\nfunction createInterpolationFormat() {\n return (value: unknown, format: string | undefined): unknown => {\n if (typeof value === 'string') {\n value = value.trim();\n }\n\n if (format === 'optional' && (value === null || value === undefined || value === '')) {\n return '';\n }\n\n switch (format) {\n case 'percentage':\n if (typeof value === 'number' && Number.isNaN(value)) return value;\n return `${Number(value)}%`;\n case 'uppercase':\n return (value || '').toString().toLocaleUpperCase();\n case 'lowercase':\n return (value || '').toString().toLocaleLowerCase();\n case 'firstchar':\n return (value || '')\n .toString()\n .split(/([.?!]+\\s*|\\n+)/g)\n .map((part: string) => {\n if (/^[.?!]+/.test(part) || /^\\s*$/.test(part)) {\n return part;\n }\n return part\n .toLocaleLowerCase()\n .replace(\n /^(\\s*)(\\S)/,\n (_, spaces, firstChar) => spaces + firstChar.toLocaleUpperCase(),\n );\n })\n .join('');\n case 'camel':\n return (value || '')\n .toString()\n .split(' ')\n .map((word: string) => {\n return word.charAt(0).toLocaleUpperCase() + (word || '').slice(1).toLocaleLowerCase();\n })\n .join(' ');\n default:\n return value;\n }\n };\n}\n\n/** One-time i18next init shared by Svelte shell and I18NextPlugin. */\nexport async function initSlotI18n(): Promise<void> {\n if (i18next.isInitialized) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n const requestedLng = resolveLanguageFromUrl();\n\n await i18next\n .use(Backend)\n .use(LanguageDetector)\n .use({\n type: 'postProcessor',\n name: 'trimProcessor',\n process(value: unknown) {\n if (typeof value === 'string') {\n return value.trim();\n }\n return value;\n },\n })\n .init({\n lng: requestedLng,\n preload: [DEFAULT_LANGUAGE],\n fallbackLng: [DEFAULT_LANGUAGE],\n load: 'currentOnly',\n debug: false,\n detection: {\n order: ['querystring', 'localStorage', 'cookie', 'navigator'],\n lookupQuerystring: 'lng',\n caches: ['localStorage', 'cookie'],\n },\n backend: {\n loadPath: resolvePublicPath('locales/{{lng}}.json'),\n queryStringParams: { v: '1.0.0' },\n },\n interpolation: {\n escapeValue: false,\n format: createInterpolationFormat(),\n },\n postProcess: ['trimProcessor'],\n });\n\n i18next.on('languageChanged', (lng) => {\n const normalized = normalizeLanguageCode(lng);\n for (const listener of languageChangedListeners) {\n listener(normalized);\n }\n });\n\n getLogger('SharedI18n').info('i18n initialized', { language: getCurrentLanguage() });\n })();\n\n try {\n await initPromise;\n } catch (error) {\n initPromise = null;\n getLogger('SharedI18n').error('Failed to initialize i18n', error);\n throw error;\n }\n}\n\nexport function t(key: string, options?: Record<string, unknown>): string {\n return i18next.t(key, options) as string;\n}\n\nexport async function changeLanguage(lng: string): Promise<void> {\n const normalized = normalizeLanguageCode(lng);\n await i18next.changeLanguage(normalized);\n}\n\nexport function getCurrentLanguage(): string {\n return normalizeLanguageCode(i18next.language);\n}\n\nexport function isI18nReady(): boolean {\n return i18next.isInitialized;\n}\n\nexport function onLanguageChanged(listener: (lng: string) => void): () => void {\n languageChangedListeners.add(listener);\n return () => {\n languageChangedListeners.delete(listener);\n };\n}\n\nexport function getI18nInstance() {\n return i18next;\n}\n"]}