From 7c402b6fa39f1e109f354d1fe86e8bc03b158bfa Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Thu, 14 Mar 2024 10:29:49 +0530 Subject: [PATCH 1/5] WASM refactoring --- docs/tutorials/js.md | 2 +- docs/tutorials/npm/gen.sh | 137 ++++++++++++++++++ docs/tutorials/npm/package.json | 2 +- docs/tutorials/npm/src/ts/app.ts | 12 +- .../npm/src/ts/data-provider-manager.ts | 124 ++++++++++++++++ docs/tutorials/npm/src/ts/date-time.ts | 56 +++++-- docs/tutorials/npm/src/ts/fixed-decimal.ts | 59 ++++++-- docs/tutorials/npm/src/ts/segmenter.ts | 12 +- 8 files changed, 372 insertions(+), 32 deletions(-) create mode 100644 docs/tutorials/npm/gen.sh create mode 100644 docs/tutorials/npm/src/ts/data-provider-manager.ts diff --git a/docs/tutorials/js.md b/docs/tutorials/js.md index 0cf42a1614e..64a5dbde7e4 100644 --- a/docs/tutorials/js.md +++ b/docs/tutorials/js.md @@ -10,7 +10,7 @@ _We are still working on improving the user experience of using ICU4X from other Similar to C++, the JS APIs mirror the Rust code in the `icu_capi` crate, which can be explored on [docs.rs][rust-docs], though the precise types used may be different. -See [`ffi/npm/examples/wasm-demo`] for an NPM package that uses the ICU4X package. You can run it using `npm run start`. +See [`docs/tutorials/npm`] for an NPM package that uses the ICU4X package. You can run it using `npm run start`. We hope to fill in these docs over time with more examples. diff --git a/docs/tutorials/npm/gen.sh b/docs/tutorials/npm/gen.sh new file mode 100644 index 00000000000..70d75118853 --- /dev/null +++ b/docs/tutorials/npm/gen.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +locales=("ja" "th" "zh" "bn" "und" "de" "en") + +for locale in "${locales[@]}"; do + icu4x-datagen --keys \ + "datetime/symbols/hebrew/years@1" \ + "segmenter/dictionary/w_auto@1" \ + "datetime/symbols/weekdays@1" \ + "datetime/symbols/dangi/months@1" \ + "time_zone/iana_to_bcp47@1" \ + "datetime/skeletons@1" \ + "time_zone/bcp47_to_iana@1" \ + "datetime/patterns/chinese/date@1" \ + "datetime/roc/datesymbols@1" \ + "datetime/patterns/coptic/date@1" \ + "datetime/symbols/persian/months@1" \ + "datetime/hebrew/datelengths@1" \ + "decimal/symbols@1" \ + "datetime/symbols/islamic/years@1" \ + "datetime/symbols/indian/months@1" \ + "locid_transform/script_dir@1" \ + "fallback/supplement/co@1" \ + "datetime/symbols/buddhist/months@1" \ + "datetime/patterns/ethiopic/date@1" \ + "plurals/ranges@1" \ + "segmenter/grapheme@1" \ + "time_zone/metazone_period@1" \ + "datetime/persian/datelengths@1" \ + "datetime/ethiopic/datesymbols@1" \ + "time_zone/generic_short@1" \ + "datetime/symbols/japanese/months@1" \ + "time_zone/generic_long@1" \ + "normalizer/nfkd@1" \ + "datetime/patterns/persian/date@1" \ + "datetime/symbols/ethiopic/months@1" \ + "datetime/patterns/buddhist/date@1" \ + "locid_transform/likelysubtags_l@1" \ + "datetime/symbols/persian/years@1" \ + "datetime/patterns/hebrew/date@1" \ + "datetime/symbols/buddhist/years@1" \ + "datetime/chinese/datelengths@1" \ + "datetime/symbols/japanext/months@1" \ + "plurals/ordinal@1" \ + "datetime/symbols/coptic/years@1" \ + "datetime/patterns/islamic/date@1" \ + "datetime/patterns/time@1" \ + "datetime/symbols/dangi/years@1" \ + "time_zone/formats@1" \ + "datetime/patterns/dangi/date@1" \ + "datetime/japanese/datelengths@1" \ + "datetime/ethiopic/datelengths@1" \ + "plurals/cardinal@1" \ + "datetime/indian/datelengths@1" \ + "segmenter/lstm/wl_auto@1" \ + "datetime/symbols/chinese/years@1" \ + "fallback/parents@1" \ + "datetime/gregory/datelengths@1" \ + "datetime/patterns/gregory/date@1" \ + "datetime/symbols/japanext/years@1" \ + "datetime/gregory/datesymbols@1" \ + "datetime/week_data@1" \ + "time_zone/exemplar_cities@1" \ + "datetime/coptic/datelengths@1" \ + "segmenter/dictionary/wl_ext@1" \ + "list/or@1" \ + "datetime/dangi/datelengths@1" \ + "datetime/persian/datesymbols@1" \ + "datetime/buddhist/datelengths@1" \ + "normalizer/nfd@1" \ + "datetime/patterns/roc/date@1" \ + "time_zone/specific_short@1" \ + "datetime/japanese/datesymbols@1" \ + "segmenter/line@1" \ + "datetime/symbols/hebrew/months@1" \ + "datetime/buddhist/datesymbols@1" \ + "datetime/symbols/ethiopic/years@1" \ + "datetime/coptic/datesymbols@1" \ + "normalizer/nfkdex@1" \ + "time_zone/specific_long@1" \ + "datetime/roc/datelengths@1" \ + "calendar/japanext@1" \ + "datetime/japanext/datesymbols@1" \ + "normalizer/decomp@1" \ + "datetime/islamic/datelengths@1" \ + "list/unit@1" \ + "datetime/timelengths@1" \ + "segmenter/word@1" \ + "datetime/dangi/datesymbols@1" \ + "datetime/islamic/datesymbols@1" \ + "datetime/symbols/gregory/months@1" \ + "datetime/timesymbols@1" \ + "datetime/symbols/japanese/years@1" \ + "datetime/patterns/japanese/date@1" \ + "datetime/indian/datesymbols@1" \ + "datetime/patterns/japanext/date@1" \ + "datetime/patterns/datetime@1" \ + "segmenter/sentence@1" \ + "datetime/symbols/chinese/months@1" \ + "locid_transform/aliases@1" \ + "datetime/symbols/roc/years@1" \ + "locid_transform/likelysubtags_sr@1" \ + "datetime/symbols/indian/years@1" \ + "datetime/chinese/datesymbols@1" \ + "normalizer/uts46d@1" \ + "locid_transform/likelysubtags@1" \ + "locid_transform/likelysubtags_ext@1" \ + "datetime/symbols/gregory/years@1" \ + "datetime/japanext/datelengths@1" \ + "datetime/symbols/coptic/months@1" \ + "datetime/hebrew/datesymbols@1" \ + "list/and@1" \ + "normalizer/comp@1" \ + "fallback/likelysubtags@1" \ + "datetime/patterns/indian/date@1" \ + "calendar/japanese@1" \ + "datetime/symbols/islamic/months@1" \ + "datetime/symbols/roc/months@1" \ + "datetime/symbols/dayperiods@1" \ + "normalizer/nfdex@1" \ + --fallback preresolved --locales $locale --format blob2 --out dist/$locale.postcard --overwrite +done + +ts_content="const locales: string[] = [" + +for locale in "${locales[@]}"; do + ts_content+="\"$locale\", " +done + +ts_content=${ts_content%, } +ts_content+="];" + +ts_content+="\nexport default locales;" + +echo "$ts_content" > dist/locales.ts + +echo "locales.ts file has been generated." \ No newline at end of file diff --git a/docs/tutorials/npm/package.json b/docs/tutorials/npm/package.json index 8c9feb5f032..00eb89e4d7e 100644 --- a/docs/tutorials/npm/package.json +++ b/docs/tutorials/npm/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "clean": "rm dist/*", - "build": "webpack", + "build": "sh gen.sh && webpack ", "start": "webpack serve --mode development --port 12349", "tsc": "tsc -p ." }, diff --git a/docs/tutorials/npm/src/ts/app.ts b/docs/tutorials/npm/src/ts/app.ts index c0d3a7a56d8..b65152ec781 100644 --- a/docs/tutorials/npm/src/ts/app.ts +++ b/docs/tutorials/npm/src/ts/app.ts @@ -1,4 +1,4 @@ -import { ICU4XDataProvider } from 'icu4x'; +import { DataProviderManager } from './data-provider-manager'; import * as fdf from './fixed-decimal'; import * as dtf from './date-time'; import * as seg from './segmenter'; @@ -8,9 +8,11 @@ import 'bootstrap/js/dist/dropdown'; import 'bootstrap/js/dist/collapse'; (async function init() { - const dataProvider = ICU4XDataProvider.create_compiled(); - fdf.setup(dataProvider); - dtf.setup(dataProvider); - seg.setup(dataProvider); + const dataManager = await DataProviderManager.create(); + + fdf.setup(dataManager); + dtf.setup(dataManager); + seg.setup(dataManager); + (document.querySelector("#bigspinner") as HTMLElement).style.display = "none"; })() \ No newline at end of file diff --git a/docs/tutorials/npm/src/ts/data-provider-manager.ts b/docs/tutorials/npm/src/ts/data-provider-manager.ts new file mode 100644 index 00000000000..82f6543e447 --- /dev/null +++ b/docs/tutorials/npm/src/ts/data-provider-manager.ts @@ -0,0 +1,124 @@ +import { + ICU4XDataProvider, + ICU4XLocale, + ICU4XLocaleFallbacker, + ICU4XLocaleFallbackConfig, + ICU4XLocaleFallbackPriority +} from 'icu4x'; +import * as localeDefault from '../../dist/locales'; + +export class DataProviderManager { + + private dataProvider: ICU4XDataProvider; + private fallbacker: ICU4XLocaleFallbacker; + private fallbackLocale: ICU4XLocale; + private loadedLocales: Set ; + + private constructor() { + this.loadedLocales = new Set < ICU4XLocale > (); + } + + public static async create(): Promise { + const manager = new DataProviderManager(); + await manager.init(); + return manager; + } + + private async init() { + + const enFilePath = 'dist/en.postcard'; + let enProvider = await this.createDataProviderFromBlob(enFilePath); + this.loadedLocales.add(ICU4XLocale.create_from_string("en")); + + const unFilePath = 'dist/en.postcard'; + let unProvider = await this.createDataProviderFromBlob(unFilePath); + + + let fallbacker = ICU4XLocaleFallbacker.create(unProvider); + let fallbackConfig = new ICU4XLocaleFallbackConfig(); + fallbackConfig.priority = ICU4XLocaleFallbackPriority.Language; + let fallbackerWithConfig = fallbacker.for_config(fallbackConfig); + + this.fallbacker = fallbackerWithConfig; + enProvider.enable_locale_fallback_with(this.fallbacker); + this.dataProvider = enProvider; + } + + private async createDataProviderFromBlob(filePath: string): Promise < ICU4XDataProvider > { + const blob = await this.readBlobFromFile(filePath); + const arrayBuffer = await blob.arrayBuffer(); + const uint8Array = new Uint8Array(arrayBuffer); + const newDataProvider = ICU4XDataProvider.create_from_byte_slice(uint8Array); + return newDataProvider; + } + + private async readBlobFromFile(path: string): Promise < Blob > { + const response = await fetch(path); + if(!response.ok) { + throw new Error(`Failed to fetch file: ${response.statusText}`); + } + const blob = await response.blob(); + return blob; + } + + public async trackLocaleFallback(fallbacker: ICU4XLocaleFallbacker, locale: ICU4XLocale): Promise < string > { + let localeSet = new Set(localeDefault.default); + const initialLocale = locale.to_string(); + let fallbackIterator = fallbacker.fallback_for_locale(locale); + while(fallbackIterator.get().to_string() != 'und') { + const fallbackLocale = fallbackIterator.get().to_string(); + if(initialLocale != fallbackLocale){ + console.log(`Tracking back to: ${fallbackLocale}`); + } + if(localeSet.has(fallbackLocale)) { + return fallbackLocale; + } + fallbackIterator.step(); + } + return 'und'; + } + + public async loadLocale(newLocale: string): Promise < ICU4XDataProvider > { + const icu4xLocale = ICU4XLocale.create_from_string(newLocale); + const fallbackLocale = await this.trackLocaleFallback(this.fallbacker, icu4xLocale); + const newFilePath = `dist/${fallbackLocale}.postcard`; + let newProvider = await this.createDataProviderFromBlob(newFilePath); + await newProvider.fork_by_locale(this.dataProvider); + this.dataProvider = newProvider; + this.loadedLocales.add(ICU4XLocale.create_from_string(fallbackLocale)); + this.fallbackLocale = ICU4XLocale.create_from_string(fallbackLocale); + return newProvider; + } + + public async getSegmenterProviderLocale () : Promise { + const segmenterLocale = ['ja', 'zh', 'th']; + let segmenterProvider: ICU4XDataProvider; + for(let i = 0 ; i < segmenterLocale.length ; i++){ + segmenterProvider = await this.loadLocale(segmenterLocale[i]); + } + return segmenterProvider; + } + + public async getDeDataProvider() { + const newFilePath = `dist/de.postcard`; + let newProvider = await this.createDataProviderFromBlob(newFilePath); + return newProvider; + } + + public getLoadedLocales() { + return this.loadedLocales; + } + + public getDataProvider(): ICU4XDataProvider { + return this.dataProvider; + } + + public getFallbacker(): ICU4XLocaleFallbacker { + return this.fallbacker; + } + + public getFallbackLocale(): ICU4XLocale { + return this.fallbackLocale; + } + +} \ No newline at end of file diff --git a/docs/tutorials/npm/src/ts/date-time.ts b/docs/tutorials/npm/src/ts/date-time.ts index 5f84f8f4a60..cd1b65fcb74 100644 --- a/docs/tutorials/npm/src/ts/date-time.ts +++ b/docs/tutorials/npm/src/ts/date-time.ts @@ -1,9 +1,24 @@ -import { ICU4XDataProvider, ICU4XDateLength, ICU4XDateTime, ICU4XDateTimeFormatter, ICU4XLocale, ICU4XTimeLength, ICU4XCalendar } from "icu4x"; -import { Ok, Result, result, unwrap } from "./index"; +import { + ICU4XDataProvider, + ICU4XDateLength, + ICU4XDateTime, + ICU4XDateTimeFormatter, + ICU4XLocale, + ICU4XTimeLength, + ICU4XCalendar +} from "icu4x"; +import { DataProviderManager } from './data-provider-manager'; +import { + Ok, + Result, + result, + unwrap +} from "./index"; export class DateTimeDemo { #displayFn: (formatted: string) => void; #dataProvider: ICU4XDataProvider; + #dataProviderManager: DataProviderManager; #localeStr: string; #calendarStr: string; @@ -16,12 +31,13 @@ export class DateTimeDemo { #formatter: Result; #dateTime: Result | null; - constructor(displayFn: (formatted: string) => void, dataProvider: ICU4XDataProvider) { + constructor(displayFn: (formatted: string) => void, dataProviderManager: DataProviderManager) { + this.#displayFn = displayFn; - this.#dataProvider = dataProvider; - + this.#dataProvider = dataProviderManager.getDataProvider(); + this.#dataProviderManager = dataProviderManager; this.#locale = Ok(ICU4XLocale.create_from_string("en")); - this.#calendar = Ok(ICU4XCalendar.create_for_locale(dataProvider, unwrap(this.#locale))); + this.#calendar = Ok(ICU4XCalendar.create_for_locale(this.#dataProvider, unwrap(this.#locale))); this.#dateLength = ICU4XDateLength.Short; this.#timeLength = ICU4XTimeLength.Short; this.#dateTime = null; @@ -37,9 +53,31 @@ export class DateTimeDemo { this.#updateFormatter(); } - setLocale(locid: string): void { - this.#localeStr = locid; - this.#updateLocaleAndCalendar(); + async setLocale(locid: string): Promise { + this.#locale = result(() => ICU4XLocale.create_from_string(locid)); + if (this.#locale.ok == true) { + const locales = this.#dataProviderManager.getLoadedLocales(); + const localesFinal: string[] = []; + locales.forEach((item: ICU4XLocale) => { + localesFinal.push(item.to_string) + }) + const loadedLocales = new Set(localesFinal); + if (!loadedLocales.has(this.#locale.value.to_string())) { + await this.updateProvider(this.#locale.value); + } + } + this.#updateFormatter() + } + + async updateProvider(newLocale: ICU4XLocale) { + this.#dataProvider = await this.#dataProviderManager.loadLocale(newLocale.to_string()); + const fallbackLocale = this.#dataProviderManager.getFallbackLocale(); + const fallbackLocaleResult = result(() => this.#dataProviderManager.getFallbackLocale()); + this.#locale = fallbackLocaleResult + // Logs if there is a fallback and prints the fallback locale + if(newLocale.to_string() != fallbackLocale.to_string()) { + console.log(`Falling back to locale: ${fallbackLocale.to_string()}`); + } this.#updateFormatter(); } diff --git a/docs/tutorials/npm/src/ts/fixed-decimal.ts b/docs/tutorials/npm/src/ts/fixed-decimal.ts index c604d3d0130..1ba5825e461 100644 --- a/docs/tutorials/npm/src/ts/fixed-decimal.ts +++ b/docs/tutorials/npm/src/ts/fixed-decimal.ts @@ -1,33 +1,68 @@ -import { ICU4XDataProvider, ICU4XFixedDecimal, ICU4XFixedDecimalFormatter, ICU4XFixedDecimalGroupingStrategy, ICU4XLocale } from "icu4x"; -import { Result, Ok, result, unwrap } from './index'; +import { + ICU4XDataProvider, + ICU4XFixedDecimal, + ICU4XFixedDecimalFormatter, + ICU4XFixedDecimalGroupingStrategy, + ICU4XLocale +} from "icu4x"; +import { DataProviderManager } from './data-provider-manager'; +import { + Result, + Ok, + result, + unwrap, +} from './index'; export class FixedDecimalDemo { #displayFn: (formatted: string) => void; #dataProvider: ICU4XDataProvider; + #dataProviderManager: DataProviderManager; #locale: Result; #groupingStrategy: ICU4XFixedDecimalGroupingStrategy; #formatter: Result; #fixedDecimal: Result | null; - constructor(displayFn: (formatted: string) => void, dataProvider: ICU4XDataProvider) { + constructor(displayFn: (formatted: string) => void, dataProviderManager: DataProviderManager) { this.#displayFn = displayFn; - this.#dataProvider = dataProvider; + this.#dataProvider = dataProviderManager.getDataProvider(); + this.#dataProviderManager = dataProviderManager; this.#locale = Ok(ICU4XLocale.create_from_string("en")); this.#groupingStrategy = ICU4XFixedDecimalGroupingStrategy.Auto; this.#fixedDecimal = null; - this.#updateFormatter() + this.#updateFormatter(); } - setLocale(locid: string): void { + async setLocale(locid: string): Promise { this.#locale = result(() => ICU4XLocale.create_from_string(locid)); - this.#updateFormatter() + if (this.#locale.ok === true) { + const locales = this.#dataProviderManager.getLoadedLocales(); + // The if case is making issue, try to fork with old. + const localesFinal: string[] = []; + locales.forEach((item: ICU4XLocale) => { + localesFinal.push(item.to_string()); + }); + const loadedLocales = new Set(localesFinal); + await this.updateProvider(this.#locale.value); + } + this.#updateFormatter(); + } + + async updateProvider(newLocale: ICU4XLocale): Promise { + this.#dataProvider = await this.#dataProviderManager.loadLocale(newLocale.to_string()); + const fallbackLocale = await this.#dataProviderManager.getFallbackLocale(); + const fallbackLocaleResult = result(() => this.#dataProviderManager.getFallbackLocale()); + this.#locale = fallbackLocaleResult; + if(newLocale.to_string() != fallbackLocale.to_string()) { + console.log(`Falling back to locale: ${fallbackLocale.to_string()}`); + } + this.#updateFormatter(); } setGroupingStrategy(strategy: string): void { this.#groupingStrategy = ICU4XFixedDecimalGroupingStrategy[strategy]; - this.#updateFormatter() + this.#updateFormatter(); } setFixedDecimal(digits: string): void { @@ -39,7 +74,7 @@ export class FixedDecimalDemo { this.#formatter = result(() => ICU4XFixedDecimalFormatter.create_with_grouping_strategy( this.#dataProvider, unwrap(this.#locale), - this.#groupingStrategy, + this.#groupingStrategy )); this.#render(); } @@ -80,16 +115,16 @@ export function setup(dataProvider: ICU4XDataProvider): void { } }); - for (let btn of document.querySelectorAll('input[name="fdf-locale"]')) { + for (let btn of document.querySelectorAll < HTMLInputElement | null > ('input[name="fdf-locale"]')) { if (btn?.value !== 'other') { btn.addEventListener('click', () => fixedDecimalDemo.setLocale(btn.value)); } } - for (let btn of document.querySelectorAll('input[name="fdf-grouping"]')) { + for (let btn of document.querySelectorAll < HTMLInputElement | null > ('input[name="fdf-grouping"]')) { btn?.addEventListener('click', () => fixedDecimalDemo.setGroupingStrategy(btn.value)); } const inputDecimal = document.getElementById('fdf-input') as HTMLTextAreaElement | null; inputDecimal?.addEventListener('input', () => fixedDecimalDemo.setFixedDecimal(inputDecimal.value)); -} +} \ No newline at end of file diff --git a/docs/tutorials/npm/src/ts/segmenter.ts b/docs/tutorials/npm/src/ts/segmenter.ts index 2a1efe6407e..f6d861a9fcf 100644 --- a/docs/tutorials/npm/src/ts/segmenter.ts +++ b/docs/tutorials/npm/src/ts/segmenter.ts @@ -1,17 +1,20 @@ import { ICU4XDataProvider, ICU4XWordSegmenter } from "icu4x"; +import { DataProviderManager } from './data-provider-manager'; export class SegmenterDemo { #displayFn: (formatted: string) => void; #dataProvider: ICU4XDataProvider; + #dataProviderManager: DataProviderManager; #segmenter: ICU4XWordSegmenter; #model: string; #text: string; - constructor(displayFn: (formatted: string) => void, dataProvider: ICU4XDataProvider) { + constructor(displayFn: (formatted: string) => void, dataProviderManager: DataProviderManager) { this.#displayFn = displayFn; - this.#dataProvider = dataProvider; - + this.#dataProvider = dataProviderManager.getDataProvider(); + this.#dataProviderManager = dataProviderManager; + this.#model = "Auto"; this.#text = ""; this.#updateSegmenter(); @@ -27,7 +30,8 @@ export class SegmenterDemo { this.#render(); } - #updateSegmenter(): void { + async #updateSegmenter(): Promise { + this.#dataProvider = await this.#dataProviderManager.getSegmenterProviderLocale(); if (this.#model === "Auto") { this.#segmenter = ICU4XWordSegmenter.create_auto(this.#dataProvider); } else if (this.#model === "LSTM") { From f7358fad7e7de457048b0c9855cc25903e965d17 Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Sat, 6 Apr 2024 08:59:48 +0530 Subject: [PATCH 2/5] fallbacker instead of fallbackerWithConfig --- tutorials/npm/src/ts/data-provider-manager.ts | 50 ++++--------------- tutorials/npm/src/ts/date-time.ts | 9 +--- tutorials/npm/src/ts/fixed-decimal.ts | 19 ++++--- 3 files changed, 20 insertions(+), 58 deletions(-) diff --git a/tutorials/npm/src/ts/data-provider-manager.ts b/tutorials/npm/src/ts/data-provider-manager.ts index 82f6543e447..62b968b6525 100644 --- a/tutorials/npm/src/ts/data-provider-manager.ts +++ b/tutorials/npm/src/ts/data-provider-manager.ts @@ -1,9 +1,7 @@ import { ICU4XDataProvider, ICU4XLocale, - ICU4XLocaleFallbacker, - ICU4XLocaleFallbackConfig, - ICU4XLocaleFallbackPriority + ICU4XLocaleFallbacker } from 'icu4x'; import * as localeDefault from '../../dist/locales'; @@ -11,11 +9,10 @@ export class DataProviderManager { private dataProvider: ICU4XDataProvider; private fallbacker: ICU4XLocaleFallbacker; - private fallbackLocale: ICU4XLocale; - private loadedLocales: Set ; + private loadedLocales: Set ; private constructor() { - this.loadedLocales = new Set < ICU4XLocale > (); + this.loadedLocales = new Set (); } public static async create(): Promise { @@ -30,17 +27,13 @@ export class DataProviderManager { let enProvider = await this.createDataProviderFromBlob(enFilePath); this.loadedLocales.add(ICU4XLocale.create_from_string("en")); - const unFilePath = 'dist/en.postcard'; + const unFilePath = 'dist/und.postcard'; let unProvider = await this.createDataProviderFromBlob(unFilePath); + let fallbacker: ICU4XLocaleFallbacker = ICU4XLocaleFallbacker.create(unProvider); + enProvider.enable_locale_fallback_with(fallbacker); - let fallbacker = ICU4XLocaleFallbacker.create(unProvider); - let fallbackConfig = new ICU4XLocaleFallbackConfig(); - fallbackConfig.priority = ICU4XLocaleFallbackPriority.Language; - let fallbackerWithConfig = fallbacker.for_config(fallbackConfig); - - this.fallbacker = fallbackerWithConfig; - enProvider.enable_locale_fallback_with(this.fallbacker); + this.fallbacker = fallbacker; this.dataProvider = enProvider; } @@ -61,32 +54,13 @@ export class DataProviderManager { return blob; } - public async trackLocaleFallback(fallbacker: ICU4XLocaleFallbacker, locale: ICU4XLocale): Promise < string > { - let localeSet = new Set(localeDefault.default); - const initialLocale = locale.to_string(); - let fallbackIterator = fallbacker.fallback_for_locale(locale); - while(fallbackIterator.get().to_string() != 'und') { - const fallbackLocale = fallbackIterator.get().to_string(); - if(initialLocale != fallbackLocale){ - console.log(`Tracking back to: ${fallbackLocale}`); - } - if(localeSet.has(fallbackLocale)) { - return fallbackLocale; - } - fallbackIterator.step(); - } - return 'und'; - } - public async loadLocale(newLocale: string): Promise < ICU4XDataProvider > { const icu4xLocale = ICU4XLocale.create_from_string(newLocale); - const fallbackLocale = await this.trackLocaleFallback(this.fallbacker, icu4xLocale); - const newFilePath = `dist/${fallbackLocale}.postcard`; + const newFilePath = `dist/${newLocale}.postcard`; let newProvider = await this.createDataProviderFromBlob(newFilePath); - await newProvider.fork_by_locale(this.dataProvider); + await this.dataProvider.fork_by_locale(newProvider); this.dataProvider = newProvider; - this.loadedLocales.add(ICU4XLocale.create_from_string(fallbackLocale)); - this.fallbackLocale = ICU4XLocale.create_from_string(fallbackLocale); + this.loadedLocales.add(ICU4XLocale.create_from_string(icu4xLocale)); return newProvider; } @@ -117,8 +91,4 @@ export class DataProviderManager { return this.fallbacker; } - public getFallbackLocale(): ICU4XLocale { - return this.fallbackLocale; - } - } \ No newline at end of file diff --git a/tutorials/npm/src/ts/date-time.ts b/tutorials/npm/src/ts/date-time.ts index cd1b65fcb74..661e8843a32 100644 --- a/tutorials/npm/src/ts/date-time.ts +++ b/tutorials/npm/src/ts/date-time.ts @@ -70,14 +70,7 @@ export class DateTimeDemo { } async updateProvider(newLocale: ICU4XLocale) { - this.#dataProvider = await this.#dataProviderManager.loadLocale(newLocale.to_string()); - const fallbackLocale = this.#dataProviderManager.getFallbackLocale(); - const fallbackLocaleResult = result(() => this.#dataProviderManager.getFallbackLocale()); - this.#locale = fallbackLocaleResult - // Logs if there is a fallback and prints the fallback locale - if(newLocale.to_string() != fallbackLocale.to_string()) { - console.log(`Falling back to locale: ${fallbackLocale.to_string()}`); - } + await this.#dataProviderManager.loadLocale(newLocale.to_string()); this.#updateFormatter(); } diff --git a/tutorials/npm/src/ts/fixed-decimal.ts b/tutorials/npm/src/ts/fixed-decimal.ts index 1ba5825e461..b2a5d2d5544 100644 --- a/tutorials/npm/src/ts/fixed-decimal.ts +++ b/tutorials/npm/src/ts/fixed-decimal.ts @@ -38,25 +38,24 @@ export class FixedDecimalDemo { this.#locale = result(() => ICU4XLocale.create_from_string(locid)); if (this.#locale.ok === true) { const locales = this.#dataProviderManager.getLoadedLocales(); - // The if case is making issue, try to fork with old. const localesFinal: string[] = []; locales.forEach((item: ICU4XLocale) => { localesFinal.push(item.to_string()); }); const loadedLocales = new Set(localesFinal); - await this.updateProvider(this.#locale.value); + if(loadedLocales.has(locid)){ + } + else{ + await this.updateProvider(locid); + } + } this.#updateFormatter(); } - async updateProvider(newLocale: ICU4XLocale): Promise { - this.#dataProvider = await this.#dataProviderManager.loadLocale(newLocale.to_string()); - const fallbackLocale = await this.#dataProviderManager.getFallbackLocale(); - const fallbackLocaleResult = result(() => this.#dataProviderManager.getFallbackLocale()); - this.#locale = fallbackLocaleResult; - if(newLocale.to_string() != fallbackLocale.to_string()) { - console.log(`Falling back to locale: ${fallbackLocale.to_string()}`); - } + async updateProvider(newLocale: string): Promise { + await this.#dataProviderManager.loadLocale(newLocale); + this.#updateFormatter(); } From 96de200975b4f37b6b455ba3bb2539bb303545d8 Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Tue, 9 Apr 2024 10:40:33 +0530 Subject: [PATCH 3/5] Fixed forked_by_locale args --- tutorials/npm/src/ts/data-provider-manager.ts | 26 +++++++------------ tutorials/npm/src/ts/fixed-decimal.ts | 13 +++------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/tutorials/npm/src/ts/data-provider-manager.ts b/tutorials/npm/src/ts/data-provider-manager.ts index 62b968b6525..ee37764e415 100644 --- a/tutorials/npm/src/ts/data-provider-manager.ts +++ b/tutorials/npm/src/ts/data-provider-manager.ts @@ -1,18 +1,16 @@ import { ICU4XDataProvider, ICU4XLocale, - ICU4XLocaleFallbacker + ICU4XLocaleFallbacker, } from 'icu4x'; -import * as localeDefault from '../../dist/locales'; export class DataProviderManager { private dataProvider: ICU4XDataProvider; - private fallbacker: ICU4XLocaleFallbacker; - private loadedLocales: Set ; + private loadedLocales: Set ; private constructor() { - this.loadedLocales = new Set (); + this.loadedLocales = new Set < ICU4XLocale > (); } public static async create(): Promise { @@ -26,14 +24,10 @@ export class DataProviderManager { const enFilePath = 'dist/en.postcard'; let enProvider = await this.createDataProviderFromBlob(enFilePath); this.loadedLocales.add(ICU4XLocale.create_from_string("en")); - - const unFilePath = 'dist/und.postcard'; + const unFilePath = 'dist/en.postcard'; let unProvider = await this.createDataProviderFromBlob(unFilePath); - - let fallbacker: ICU4XLocaleFallbacker = ICU4XLocaleFallbacker.create(unProvider); + let fallbacker = ICU4XLocaleFallbacker.create(unProvider); enProvider.enable_locale_fallback_with(fallbacker); - - this.fallbacker = fallbacker; this.dataProvider = enProvider; } @@ -54,14 +48,15 @@ export class DataProviderManager { return blob; } + + public async loadLocale(newLocale: string): Promise < ICU4XDataProvider > { const icu4xLocale = ICU4XLocale.create_from_string(newLocale); const newFilePath = `dist/${newLocale}.postcard`; let newProvider = await this.createDataProviderFromBlob(newFilePath); await this.dataProvider.fork_by_locale(newProvider); - this.dataProvider = newProvider; - this.loadedLocales.add(ICU4XLocale.create_from_string(icu4xLocale)); - return newProvider; + this.loadedLocales.add(ICU4XLocale.create_from_string(newLocale)); + return this.dataProvider; } public async getSegmenterProviderLocale () : Promise { @@ -87,8 +82,5 @@ export class DataProviderManager { return this.dataProvider; } - public getFallbacker(): ICU4XLocaleFallbacker { - return this.fallbacker; - } } \ No newline at end of file diff --git a/tutorials/npm/src/ts/fixed-decimal.ts b/tutorials/npm/src/ts/fixed-decimal.ts index b2a5d2d5544..c41fcf82cee 100644 --- a/tutorials/npm/src/ts/fixed-decimal.ts +++ b/tutorials/npm/src/ts/fixed-decimal.ts @@ -38,24 +38,19 @@ export class FixedDecimalDemo { this.#locale = result(() => ICU4XLocale.create_from_string(locid)); if (this.#locale.ok === true) { const locales = this.#dataProviderManager.getLoadedLocales(); + // The if case is making issue, try to fork with old. const localesFinal: string[] = []; locales.forEach((item: ICU4XLocale) => { localesFinal.push(item.to_string()); }); const loadedLocales = new Set(localesFinal); - if(loadedLocales.has(locid)){ - } - else{ - await this.updateProvider(locid); - } - + await this.updateProvider(this.#locale.value); } this.#updateFormatter(); } - async updateProvider(newLocale: string): Promise { - await this.#dataProviderManager.loadLocale(newLocale); - + async updateProvider(newLocale: ICU4XLocale): Promise { + this.#dataProvider = await this.#dataProviderManager.loadLocale(newLocale.to_string()); this.#updateFormatter(); } From c100c7ebe1ce77197f5a2c41b00a843969f6b1aa Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Thu, 11 Apr 2024 11:26:41 +0530 Subject: [PATCH 4/5] sorted gen.sh, cached data, switch to cargo run --- tutorials/npm/.gitignore | 1 + tutorials/npm/gen.sh | 197 +++++++++++++++++------------------- tutorials/npm/gen_helper.js | 47 +++++++++ tutorials/npm/package.json | 2 +- 4 files changed, 144 insertions(+), 103 deletions(-) create mode 100644 tutorials/npm/gen_helper.js diff --git a/tutorials/npm/.gitignore b/tutorials/npm/.gitignore index a261f291755..2e51cd4a348 100644 --- a/tutorials/npm/.gitignore +++ b/tutorials/npm/.gitignore @@ -1 +1,2 @@ dist/* +gen_hash.txt \ No newline at end of file diff --git a/tutorials/npm/gen.sh b/tutorials/npm/gen.sh index 70d75118853..f27ec283509 100644 --- a/tutorials/npm/gen.sh +++ b/tutorials/npm/gen.sh @@ -3,122 +3,115 @@ locales=("ja" "th" "zh" "bn" "und" "de" "en") for locale in "${locales[@]}"; do - icu4x-datagen --keys \ - "datetime/symbols/hebrew/years@1" \ - "segmenter/dictionary/w_auto@1" \ - "datetime/symbols/weekdays@1" \ - "datetime/symbols/dangi/months@1" \ - "time_zone/iana_to_bcp47@1" \ - "datetime/skeletons@1" \ - "time_zone/bcp47_to_iana@1" \ + cargo run --package icu_datagen -- --keys \ + "calendar/japanese@1" \ + "calendar/japanext@1" \ + "datetime/buddhist/datelengths@1" \ + "datetime/buddhist/datesymbols@1" \ + "datetime/chinese/datelengths@1" \ + "datetime/chinese/datesymbols@1" \ + "datetime/coptic/datelengths@1" \ + "datetime/coptic/datesymbols@1" \ + "datetime/dangi/datelengths@1" \ + "datetime/dangi/datesymbols@1" \ + "datetime/ethiopic/datelengths@1" \ + "datetime/ethiopic/datesymbols@1" \ + "datetime/gregory/datelengths@1" \ + "datetime/gregory/datesymbols@1" \ + "datetime/hebrew/datelengths@1" \ + "datetime/hebrew/datesymbols@1" \ + "datetime/indian/datelengths@1" \ + "datetime/indian/datesymbols@1" \ + "datetime/islamic/datelengths@1" \ + "datetime/islamic/datesymbols@1" \ + "datetime/japanese/datelengths@1" \ + "datetime/japanese/datesymbols@1" \ + "datetime/japanext/datelengths@1" \ + "datetime/japanext/datesymbols@1" \ + "datetime/patterns/buddhist/date@1" \ "datetime/patterns/chinese/date@1" \ - "datetime/roc/datesymbols@1" \ "datetime/patterns/coptic/date@1" \ - "datetime/symbols/persian/months@1" \ - "datetime/hebrew/datelengths@1" \ - "decimal/symbols@1" \ - "datetime/symbols/islamic/years@1" \ - "datetime/symbols/indian/months@1" \ - "locid_transform/script_dir@1" \ - "fallback/supplement/co@1" \ - "datetime/symbols/buddhist/months@1" \ + "datetime/patterns/dangi/date@1" \ + "datetime/patterns/datetime@1" \ "datetime/patterns/ethiopic/date@1" \ - "plurals/ranges@1" \ - "segmenter/grapheme@1" \ - "time_zone/metazone_period@1" \ - "datetime/persian/datelengths@1" \ - "datetime/ethiopic/datesymbols@1" \ - "time_zone/generic_short@1" \ - "datetime/symbols/japanese/months@1" \ - "time_zone/generic_long@1" \ - "normalizer/nfkd@1" \ - "datetime/patterns/persian/date@1" \ - "datetime/symbols/ethiopic/months@1" \ - "datetime/patterns/buddhist/date@1" \ - "locid_transform/likelysubtags_l@1" \ - "datetime/symbols/persian/years@1" \ + "datetime/patterns/gregory/date@1" \ "datetime/patterns/hebrew/date@1" \ - "datetime/symbols/buddhist/years@1" \ - "datetime/chinese/datelengths@1" \ - "datetime/symbols/japanext/months@1" \ - "plurals/ordinal@1" \ - "datetime/symbols/coptic/years@1" \ + "datetime/patterns/indian/date@1" \ "datetime/patterns/islamic/date@1" \ + "datetime/patterns/japanese/date@1" \ + "datetime/patterns/japanext/date@1" \ + "datetime/patterns/persian/date@1" \ + "datetime/patterns/roc/date@1" \ "datetime/patterns/time@1" \ - "datetime/symbols/dangi/years@1" \ - "time_zone/formats@1" \ - "datetime/patterns/dangi/date@1" \ - "datetime/japanese/datelengths@1" \ - "datetime/ethiopic/datelengths@1" \ - "plurals/cardinal@1" \ - "datetime/indian/datelengths@1" \ - "segmenter/lstm/wl_auto@1" \ + "datetime/persian/datelengths@1" \ + "datetime/persian/datesymbols@1" \ + "datetime/roc/datelengths@1" \ + "datetime/roc/datesymbols@1" \ + "datetime/skeletons@1" \ + "datetime/symbols/buddhist/months@1" \ + "datetime/symbols/buddhist/years@1" \ + "datetime/symbols/chinese/months@1" \ "datetime/symbols/chinese/years@1" \ - "fallback/parents@1" \ - "datetime/gregory/datelengths@1" \ - "datetime/patterns/gregory/date@1" \ + "datetime/symbols/coptic/months@1" \ + "datetime/symbols/coptic/years@1" \ + "datetime/symbols/dangi/months@1" \ + "datetime/symbols/dangi/years@1" \ + "datetime/symbols/dayperiods@1" \ + "datetime/symbols/ethiopic/months@1" \ + "datetime/symbols/ethiopic/years@1" \ + "datetime/symbols/gregory/months@1" \ + "datetime/symbols/gregory/years@1" \ + "datetime/symbols/hebrew/months@1" \ + "datetime/symbols/hebrew/years@1" \ + "datetime/symbols/indian/months@1" \ + "datetime/symbols/indian/years@1" \ + "datetime/symbols/islamic/months@1" \ + "datetime/symbols/islamic/years@1" \ + "datetime/symbols/japanese/months@1" \ + "datetime/symbols/japanese/years@1" \ + "datetime/symbols/japanext/months@1" \ "datetime/symbols/japanext/years@1" \ - "datetime/gregory/datesymbols@1" \ + "datetime/symbols/persian/months@1" \ + "datetime/symbols/persian/years@1" \ + "datetime/symbols/roc/months@1" \ + "datetime/symbols/roc/years@1" \ + "datetime/symbols/weekdays@1" \ + "datetime/timelengths@1" \ + "datetime/timesymbols@1" \ "datetime/week_data@1" \ - "time_zone/exemplar_cities@1" \ - "datetime/coptic/datelengths@1" \ - "segmenter/dictionary/wl_ext@1" \ + "decimal/symbols@1" \ + "fallback/likelysubtags@1" \ + "fallback/parents@1" \ + "fallback/supplement/co@1" \ + "list/and@1" \ "list/or@1" \ - "datetime/dangi/datelengths@1" \ - "datetime/persian/datesymbols@1" \ - "datetime/buddhist/datelengths@1" \ - "normalizer/nfd@1" \ - "datetime/patterns/roc/date@1" \ - "time_zone/specific_short@1" \ - "datetime/japanese/datesymbols@1" \ - "segmenter/line@1" \ - "datetime/symbols/hebrew/months@1" \ - "datetime/buddhist/datesymbols@1" \ - "datetime/symbols/ethiopic/years@1" \ - "datetime/coptic/datesymbols@1" \ - "normalizer/nfkdex@1" \ - "time_zone/specific_long@1" \ - "datetime/roc/datelengths@1" \ - "calendar/japanext@1" \ - "datetime/japanext/datesymbols@1" \ - "normalizer/decomp@1" \ - "datetime/islamic/datelengths@1" \ "list/unit@1" \ - "datetime/timelengths@1" \ - "segmenter/word@1" \ - "datetime/dangi/datesymbols@1" \ - "datetime/islamic/datesymbols@1" \ - "datetime/symbols/gregory/months@1" \ - "datetime/timesymbols@1" \ - "datetime/symbols/japanese/years@1" \ - "datetime/patterns/japanese/date@1" \ - "datetime/indian/datesymbols@1" \ - "datetime/patterns/japanext/date@1" \ - "datetime/patterns/datetime@1" \ - "segmenter/sentence@1" \ - "datetime/symbols/chinese/months@1" \ "locid_transform/aliases@1" \ - "datetime/symbols/roc/years@1" \ - "locid_transform/likelysubtags_sr@1" \ - "datetime/symbols/indian/years@1" \ - "datetime/chinese/datesymbols@1" \ - "normalizer/uts46d@1" \ "locid_transform/likelysubtags@1" \ "locid_transform/likelysubtags_ext@1" \ - "datetime/symbols/gregory/years@1" \ - "datetime/japanext/datelengths@1" \ - "datetime/symbols/coptic/months@1" \ - "datetime/hebrew/datesymbols@1" \ - "list/and@1" \ - "normalizer/comp@1" \ - "fallback/likelysubtags@1" \ - "datetime/patterns/indian/date@1" \ - "calendar/japanese@1" \ - "datetime/symbols/islamic/months@1" \ - "datetime/symbols/roc/months@1" \ - "datetime/symbols/dayperiods@1" \ - "normalizer/nfdex@1" \ - --fallback preresolved --locales $locale --format blob2 --out dist/$locale.postcard --overwrite + "locid_transform/likelysubtags_l@1" \ + "locid_transform/likelysubtags_sr@1" \ + "locid_transform/script_dir@1" \ + "plurals/cardinal@1" \ + "plurals/ordinal@1" \ + "plurals/ranges@1" \ + "segmenter/dictionary/w_auto@1" \ + "segmenter/dictionary/wl_ext@1" \ + "segmenter/grapheme@1" \ + "segmenter/line@1" \ + "segmenter/lstm/wl_auto@1" \ + "segmenter/sentence@1" \ + "segmenter/word@1" \ + "time_zone/bcp47_to_iana@1" \ + "time_zone/exemplar_cities@1" \ + "time_zone/formats@1" \ + "time_zone/generic_long@1" \ + "time_zone/generic_short@1" \ + "time_zone/iana_to_bcp47@1" \ + "time_zone/metazone_period@1" \ + "time_zone/specific_long@1" \ + "time_zone/specific_short@1" \ + --locales $locale --format blob2 --out dist/$locale.postcard --overwrite done ts_content="const locales: string[] = [" diff --git a/tutorials/npm/gen_helper.js b/tutorials/npm/gen_helper.js new file mode 100644 index 00000000000..2e8c68ab5dd --- /dev/null +++ b/tutorials/npm/gen_helper.js @@ -0,0 +1,47 @@ +import fs from 'fs'; +import crypto from 'crypto'; +import { spawn } from 'child_process'; + +const genShFile = 'gen.sh'; +const hashFile = 'gen_hash.txt'; + +function calculateHash(filePath) { + const hash = crypto.createHash('sha256'); + const fileData = fs.readFileSync(filePath); + hash.update(fileData); + return hash.digest('hex'); +} + +function runGenSh() { + console.log('Running gen.sh...'); + const genShProcess = spawn('sh', [genShFile]); + + genShProcess.stdout.on('data', (data) => { + console.log(data.toString()); + }); + + genShProcess.stderr.on('data', (data) => { + console.error(data.toString()); + }); + + genShProcess.on('close', (code) => { + if (code !== 0) { + console.error(`gen.sh exited with code ${code}`); + } + }); +} + +try { + const currentHash = calculateHash(genShFile); + const previousHash = fs.existsSync(hashFile) ? fs.readFileSync(hashFile, 'utf-8') : null; + + if (currentHash !== previousHash) { + runGenSh(); + fs.writeFileSync(hashFile, currentHash); + console.log('gen.sh has been updated. Output regenerated.'); + } else { + console.log('gen.sh has not changed. Skipping execution.'); + } +} catch (error) { + console.error('An error occurred:', error); +} diff --git a/tutorials/npm/package.json b/tutorials/npm/package.json index 8d5b493eac6..28c4b2e6bf5 100644 --- a/tutorials/npm/package.json +++ b/tutorials/npm/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "clean": "rm dist/*", - "build": "sh gen.sh && webpack ", + "build": "node gen_helper.js && webpack", "start": "webpack serve --mode development --port 12349", "tsc": "tsc -p ." }, From cdd673096a127c8984991e81c985a2b6a04ac135 Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Thu, 11 Apr 2024 11:52:52 +0530 Subject: [PATCH 5/5] Implemented suggestion supportsLocale --- tutorials/npm/gen.sh | 7 +++- tutorials/npm/src/ts/data-provider-manager.ts | 35 ++++++++++--------- tutorials/npm/src/ts/date-time.ts | 10 ++---- tutorials/npm/src/ts/fixed-decimal.ts | 17 ++++----- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/tutorials/npm/gen.sh b/tutorials/npm/gen.sh index f27ec283509..a05095e5124 100644 --- a/tutorials/npm/gen.sh +++ b/tutorials/npm/gen.sh @@ -2,6 +2,11 @@ locales=("ja" "th" "zh" "bn" "und" "de" "en") +if [ ! -d "dist" ]; then + mkdir dist + echo "dist folder created." +fi + for locale in "${locales[@]}"; do cargo run --package icu_datagen -- --keys \ "calendar/japanese@1" \ @@ -111,7 +116,7 @@ for locale in "${locales[@]}"; do "time_zone/metazone_period@1" \ "time_zone/specific_long@1" \ "time_zone/specific_short@1" \ - --locales $locale --format blob2 --out dist/$locale.postcard --overwrite + --fallback preresolved --locales $locale --format blob2 --out dist/$locale.postcard --overwrite done ts_content="const locales: string[] = [" diff --git a/tutorials/npm/src/ts/data-provider-manager.ts b/tutorials/npm/src/ts/data-provider-manager.ts index ee37764e415..f0164a316fe 100644 --- a/tutorials/npm/src/ts/data-provider-manager.ts +++ b/tutorials/npm/src/ts/data-provider-manager.ts @@ -7,13 +7,13 @@ import { export class DataProviderManager { private dataProvider: ICU4XDataProvider; - private loadedLocales: Set ; + private loadedLocales: Set; private constructor() { - this.loadedLocales = new Set < ICU4XLocale > (); + this.loadedLocales = new Set(); } - public static async create(): Promise { + public static async create(): Promise { const manager = new DataProviderManager(); await manager.init(); return manager; @@ -31,7 +31,7 @@ export class DataProviderManager { this.dataProvider = enProvider; } - private async createDataProviderFromBlob(filePath: string): Promise < ICU4XDataProvider > { + private async createDataProviderFromBlob(filePath: string): Promise { const blob = await this.readBlobFromFile(filePath); const arrayBuffer = await blob.arrayBuffer(); const uint8Array = new Uint8Array(arrayBuffer); @@ -39,18 +39,26 @@ export class DataProviderManager { return newDataProvider; } - private async readBlobFromFile(path: string): Promise < Blob > { + private async readBlobFromFile(path: string): Promise { const response = await fetch(path); - if(!response.ok) { + if (!response.ok) { throw new Error(`Failed to fetch file: ${response.statusText}`); } const blob = await response.blob(); return blob; } + public supportsLocale(locid: string): boolean { + const locales = this.getLoadedLocales(); + const localesFinal: string[] = []; + locales.forEach((item: ICU4XLocale) => { + localesFinal.push(item.to_string) + }) + const loadedLocales = new Set(localesFinal); + return loadedLocales.has(locid); + } - - public async loadLocale(newLocale: string): Promise < ICU4XDataProvider > { + public async loadLocale(newLocale: string): Promise { const icu4xLocale = ICU4XLocale.create_from_string(newLocale); const newFilePath = `dist/${newLocale}.postcard`; let newProvider = await this.createDataProviderFromBlob(newFilePath); @@ -59,21 +67,15 @@ export class DataProviderManager { return this.dataProvider; } - public async getSegmenterProviderLocale () : Promise { + public async getSegmenterProviderLocale(): Promise { const segmenterLocale = ['ja', 'zh', 'th']; let segmenterProvider: ICU4XDataProvider; - for(let i = 0 ; i < segmenterLocale.length ; i++){ + for (let i = 0; i < segmenterLocale.length; i++) { segmenterProvider = await this.loadLocale(segmenterLocale[i]); } return segmenterProvider; } - public async getDeDataProvider() { - const newFilePath = `dist/de.postcard`; - let newProvider = await this.createDataProviderFromBlob(newFilePath); - return newProvider; - } - public getLoadedLocales() { return this.loadedLocales; } @@ -82,5 +84,4 @@ export class DataProviderManager { return this.dataProvider; } - } \ No newline at end of file diff --git a/tutorials/npm/src/ts/date-time.ts b/tutorials/npm/src/ts/date-time.ts index 661e8843a32..cfeeafd4152 100644 --- a/tutorials/npm/src/ts/date-time.ts +++ b/tutorials/npm/src/ts/date-time.ts @@ -56,15 +56,9 @@ export class DateTimeDemo { async setLocale(locid: string): Promise { this.#locale = result(() => ICU4XLocale.create_from_string(locid)); if (this.#locale.ok == true) { - const locales = this.#dataProviderManager.getLoadedLocales(); - const localesFinal: string[] = []; - locales.forEach((item: ICU4XLocale) => { - localesFinal.push(item.to_string) - }) - const loadedLocales = new Set(localesFinal); - if (!loadedLocales.has(this.#locale.value.to_string())) { + if(!this.#dataProviderManager.supportsLocale(locid)){ await this.updateProvider(this.#locale.value); - } + } } this.#updateFormatter() } diff --git a/tutorials/npm/src/ts/fixed-decimal.ts b/tutorials/npm/src/ts/fixed-decimal.ts index c41fcf82cee..e111c3fbbf5 100644 --- a/tutorials/npm/src/ts/fixed-decimal.ts +++ b/tutorials/npm/src/ts/fixed-decimal.ts @@ -34,19 +34,14 @@ export class FixedDecimalDemo { this.#updateFormatter(); } - async setLocale(locid: string): Promise { + async setLocale(locid: string): Promise { this.#locale = result(() => ICU4XLocale.create_from_string(locid)); - if (this.#locale.ok === true) { - const locales = this.#dataProviderManager.getLoadedLocales(); - // The if case is making issue, try to fork with old. - const localesFinal: string[] = []; - locales.forEach((item: ICU4XLocale) => { - localesFinal.push(item.to_string()); - }); - const loadedLocales = new Set(localesFinal); - await this.updateProvider(this.#locale.value); + if (this.#locale.ok == true) { + if(!this.#dataProviderManager.supportsLocale(locid)){ + await this.updateProvider(this.#locale.value); + } } - this.#updateFormatter(); + this.#updateFormatter() } async updateProvider(newLocale: ICU4XLocale): Promise {