@symbiote-native/localization 0.1.0 → 0.2.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.
@@ -1,3 +1,3 @@
1
1
  export { LocalesService } from './services/locales.service';
2
2
  export { CalendarsService } from './services/calendars.service';
3
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, type Locale, type Calendar, type EventSubscription, } from '../core';
3
+ export * from '../core';
@@ -4,4 +4,4 @@
4
4
  // hooks.
5
5
  export { LocalesService } from './services/locales.service/index.js';
6
6
  export { CalendarsService } from './services/calendars.service/index.js';
7
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, } from '../core/index.js';
7
+ export * from '../core/index.js';
@@ -1,11 +1,9 @@
1
1
  // Hand-ported from .vendors/expo/packages/expo-localization/src/ExpoLocalization.native.ts
2
- // (sdk-57). getLocales()/getCalendars() are synchronous, JSI-bridged native calls (no await) —
3
- // the native module itself implements them as sync-bridged functions, the same constants-style
4
- // read pattern this repo already uses for expo-device's eagerly-resolved fields
2
+ // (sdk-57). getLocales()/getCalendars() are synchronous, JSI-bridged native calls (no await) -
3
+ // same constants-style read pattern as expo-device's eagerly-resolved fields
5
4
  // (packages/device/src/core/native-module.ts). One native module fans out two independent event
6
- // streams (locale settings vs calendar settings) through the same addListener, keyed by event
7
- // name — mirrors the three-event-names-on-one-addListener overload trick in
8
- // packages/battery/src/core/native-module.ts.
5
+ // streams (locale vs calendar settings) through the same addListener, keyed by event name -
6
+ // mirrors the overload trick in packages/battery/src/core/native-module.ts.
9
7
  import { requireNativeModule } from 'expo-modules-core';
10
8
  const EXPO_LOCALIZATION_MODULE_NAME = 'ExpoLocalization';
11
9
  const ExpoLocalizationModule = requireNativeModule(EXPO_LOCALIZATION_MODULE_NAME);
@@ -1,3 +1,3 @@
1
1
  export { useLocales } from './hooks/use-locales';
2
2
  export { useCalendars } from './hooks/use-calendars';
3
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, type Locale, type Calendar, type EventSubscription, } from '../core';
3
+ export * from '../core';
@@ -4,4 +4,4 @@
4
4
  // naming convention of adapters/react/src/hooks (never `composables`, that's Vue's term).
5
5
  export { useLocales } from './hooks/use-locales/index.js';
6
6
  export { useCalendars } from './hooks/use-calendars/index.js';
7
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, } from '../core/index.js';
7
+ export * from '../core/index.js';
@@ -0,0 +1,3 @@
1
+ export { useLocales } from './runes/use-locales.svelte';
2
+ export { useCalendars } from './runes/use-calendars.svelte';
3
+ export * from '../core';
@@ -0,0 +1,8 @@
1
+ // @symbiote-native/localization/svelte: the Svelte entry over the framework-agnostic core. Locales
2
+ // and calendars each get their own lifecycle rune, matching upstream's own useLocales/
3
+ // useCalendars being two separate hooks, not one combined hook — mirrors the lifecycle-bucket
4
+ // naming convention of adapters/svelte/src/runes (never `hooks`/`composables`, those are React's
5
+ // and Vue's terms).
6
+ export { useLocales } from './runes/use-locales.svelte';
7
+ export { useCalendars } from './runes/use-calendars.svelte';
8
+ export * from '../core/index.js';
@@ -0,0 +1,4 @@
1
+ import { type Calendar } from '../../core';
2
+ export declare function useCalendars(): {
3
+ readonly current: Calendar[];
4
+ };
@@ -0,0 +1,21 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core — mirrors use-locales' shape exactly.
2
+ // See use-locales.svelte.ts's header for why this lives in `runes/` with a `.svelte.ts` extension
3
+ // and returns a boxed getter object instead of a bare `$state` variable.
4
+ import { addCalendarListener, getCalendars, } from '../../core/index.js';
5
+ export function useCalendars() {
6
+ let calendars = $state(getCalendars());
7
+ $effect(() => {
8
+ // Write-only touch of `calendars` (see use-locales.svelte.ts) — the effect stays
9
+ // dependency-free and so runs once on mount, cleaning up once on unmount.
10
+ calendars = getCalendars();
11
+ const subscription = addCalendarListener(() => {
12
+ calendars = getCalendars();
13
+ });
14
+ return () => subscription.remove();
15
+ });
16
+ return {
17
+ get current() {
18
+ return calendars;
19
+ },
20
+ };
21
+ }
@@ -0,0 +1,4 @@
1
+ import { type Locale } from '../../core';
2
+ export declare function useLocales(): {
3
+ readonly current: Locale[];
4
+ };
@@ -0,0 +1,27 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core (core/localization.ts). getLocales()
2
+ // is a synchronous native call, so state is seeded at call time - the `$effect` only wires the
3
+ // change listener, the twin of Vue's onMounted/onUnmounted pair.
4
+ //
5
+ // `.svelte.ts` extension: runes ($state/$effect) only work there outside a `.svelte` component;
6
+ // `runes/` is Svelte's name for the lifecycle bucket (React's `hooks/`, Vue's `composables/`).
7
+ // Returns a boxed getter, not a bare `$state`: Svelte 5 reactivity is lexically scoped to the
8
+ // declaring module and doesn't survive being returned raw from a plain function, so the caller
9
+ // reads `.current` like unwrapping Vue's `Ref` via `.value`.
10
+ import { addLocaleListener, getLocales } from '../../core/index.js';
11
+ export function useLocales() {
12
+ let locales = $state(getLocales());
13
+ $effect(() => {
14
+ // Re-read on mount in case locales changed between this call and the effect running. This
15
+ // write never reads `locales`, so the effect has no dependency on it and fires once per mount.
16
+ locales = getLocales();
17
+ const subscription = addLocaleListener(() => {
18
+ locales = getLocales();
19
+ });
20
+ return () => subscription.remove();
21
+ });
22
+ return {
23
+ get current() {
24
+ return locales;
25
+ },
26
+ };
27
+ }
@@ -1,3 +1,3 @@
1
1
  export { useLocales } from './composables/use-locales';
2
2
  export { useCalendars } from './composables/use-calendars';
3
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, type Locale, type Calendar, type EventSubscription, } from '../core';
3
+ export * from '../core';
@@ -4,4 +4,4 @@
4
4
  // naming convention of adapters/vue/src/composables (never `hooks`, that's React's term).
5
5
  export { useLocales } from './composables/use-locales/index.js';
6
6
  export { useCalendars } from './composables/use-calendars/index.js';
7
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, } from '../core/index.js';
7
+ export * from '../core/index.js';
@@ -1,3 +1,3 @@
1
1
  export { LocalesService } from './services/locales.service';
2
2
  export { CalendarsService } from './services/calendars.service';
3
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, type Locale, type Calendar, type EventSubscription, } from '../core';
3
+ export * from '../core';
@@ -4,5 +4,5 @@
4
4
  // hooks.
5
5
  export { LocalesService } from './services/locales.service';
6
6
  export { CalendarsService } from './services/calendars.service';
7
- export { getLocales, getCalendars, addLocaleListener, addCalendarListener, Weekday, CalendarIdentifier, } from '../core';
7
+ export * from '../core';
8
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6FAA6F;AAC7F,iGAAiG;AACjG,SAAS;AACT,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EACL,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,OAAO,EACP,kBAAkB,GAInB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6FAA6F;AAC7F,iGAAiG;AACjG,SAAS;AACT,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,cAAc,SAAS,CAAC"}
@@ -17,10 +17,10 @@ export class CalendarsService {
17
17
  }, { injector: this.injector });
18
18
  return calendars.asReadonly();
19
19
  }
20
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CalendarsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
21
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CalendarsService, providedIn: 'root' });
20
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CalendarsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
21
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CalendarsService, providedIn: 'root' });
22
22
  }
23
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CalendarsService, decorators: [{
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CalendarsService, decorators: [{
24
24
  type: Injectable,
25
25
  args: [{ providedIn: 'root' }]
26
26
  }] });
@@ -18,10 +18,10 @@ export class LocalesService {
18
18
  }, { injector: this.injector });
19
19
  return locales.asReadonly();
20
20
  }
21
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LocalesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
22
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LocalesService, providedIn: 'root' });
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LocalesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
22
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LocalesService, providedIn: 'root' });
23
23
  }
24
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LocalesService, decorators: [{
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LocalesService, decorators: [{
25
25
  type: Injectable,
26
26
  args: [{ providedIn: 'root' }]
27
27
  }] });
@@ -1,11 +1,9 @@
1
1
  // Hand-ported from .vendors/expo/packages/expo-localization/src/ExpoLocalization.native.ts
2
- // (sdk-57). getLocales()/getCalendars() are synchronous, JSI-bridged native calls (no await) —
3
- // the native module itself implements them as sync-bridged functions, the same constants-style
4
- // read pattern this repo already uses for expo-device's eagerly-resolved fields
2
+ // (sdk-57). getLocales()/getCalendars() are synchronous, JSI-bridged native calls (no await) -
3
+ // same constants-style read pattern as expo-device's eagerly-resolved fields
5
4
  // (packages/device/src/core/native-module.ts). One native module fans out two independent event
6
- // streams (locale settings vs calendar settings) through the same addListener, keyed by event
7
- // name — mirrors the three-event-names-on-one-addListener overload trick in
8
- // packages/battery/src/core/native-module.ts.
5
+ // streams (locale vs calendar settings) through the same addListener, keyed by event name -
6
+ // mirrors the overload trick in packages/battery/src/core/native-module.ts.
9
7
  import { requireNativeModule } from 'expo-modules-core';
10
8
  const EXPO_LOCALIZATION_MODULE_NAME = 'ExpoLocalization';
11
9
  const ExpoLocalizationModule = requireNativeModule(EXPO_LOCALIZATION_MODULE_NAME);
@@ -1 +1 @@
1
- {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,+FAA+F;AAC/F,+FAA+F;AAC/F,gFAAgF;AAChF,gGAAgG;AAChG,8FAA8F;AAC9F,4EAA4E;AAC5E,8CAA8C;AAC9C,OAAO,EAA0B,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGhF,MAAM,6BAA6B,GAAG,kBAAkB,CAAC;AAezD,MAAM,sBAAsB,GAAG,mBAAmB,CAChD,6BAA6B,CAC9B,CAAC;AAEF,MAAM,UAAU,iBAAiB;AAC/B,oFAAoF;AACpF,iFAAiF;AACjF,QAAmC;IAEnC,OAAO,sBAAsB,CAAC,WAAW,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAmC;IACrE,OAAO,sBAAsB,CAAC,WAAW,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;AACnF,CAAC;AAED,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,+FAA+F;AAC/F,6EAA6E;AAC7E,gGAAgG;AAChG,4FAA4F;AAC5F,4EAA4E;AAC5E,OAAO,EAA0B,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGhF,MAAM,6BAA6B,GAAG,kBAAkB,CAAC;AAezD,MAAM,sBAAsB,GAAG,mBAAmB,CAChD,6BAA6B,CAC9B,CAAC;AAEF,MAAM,UAAU,iBAAiB;AAC/B,oFAAoF;AACpF,iFAAiF;AACjF,QAAmC;IAEnC,OAAO,sBAAsB,CAAC,WAAW,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAmC;IACrE,OAAO,sBAAsB,CAAC,WAAW,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;AACnF,CAAC;AAED,eAAe,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/localization",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "expo-localization wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, and Angular adapters. Two independent synchronous getters (getLocales, getCalendars), each with its own native change listener and its own reactive hook per adapter.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -30,6 +30,10 @@
30
30
  "types": "./build/react/index.d.ts",
31
31
  "default": "./build/react/index.js"
32
32
  },
33
+ "./svelte": {
34
+ "types": "./build/svelte/index.d.ts",
35
+ "default": "./build/svelte/index.js"
36
+ },
33
37
  "./angular": {
34
38
  "types": "./build-ngc/angular/index.d.ts",
35
39
  "react-native": "./build-ngc/angular/index.js",
@@ -53,15 +57,17 @@
53
57
  "expo-modules-core": "57.0.5"
54
58
  },
55
59
  "peerDependencies": {
60
+ "@symbiote-native/angular": ">=0.6.2",
56
61
  "@symbiote-native/engine": ">=0.1.7",
62
+ "@symbiote-native/react": ">=0.2.8",
63
+ "@symbiote-native/svelte": ">=0.1.0",
64
+ "@symbiote-native/vue": ">=0.3.8",
57
65
  "@angular/core": ">=20",
58
66
  "@vue/runtime-core": "^3.5.13",
59
67
  "react": ">=19.0.0",
60
68
  "react-native": ">=0.86",
61
- "vue": ">=3.5.0",
62
- "@symbiote-native/angular": "0.6.2",
63
- "@symbiote-native/react": "0.2.8",
64
- "@symbiote-native/vue": "0.3.8"
69
+ "svelte": ">=5.56.0",
70
+ "vue": ">=3.5.0"
65
71
  },
66
72
  "peerDependenciesMeta": {
67
73
  "@symbiote-native/angular": {
@@ -70,6 +76,9 @@
70
76
  "@symbiote-native/react": {
71
77
  "optional": true
72
78
  },
79
+ "@symbiote-native/svelte": {
80
+ "optional": true
81
+ },
73
82
  "@symbiote-native/vue": {
74
83
  "optional": true
75
84
  },
@@ -82,24 +91,29 @@
82
91
  "react": {
83
92
  "optional": true
84
93
  },
94
+ "svelte": {
95
+ "optional": true
96
+ },
85
97
  "vue": {
86
98
  "optional": true
87
99
  }
88
100
  },
89
101
  "devDependencies": {
90
- "@angular/compiler": "^22",
91
- "@angular/compiler-cli": "^22",
92
- "@angular/core": "^22",
102
+ "@angular/compiler": "~22.0.8",
103
+ "@angular/compiler-cli": "~22.0.8",
104
+ "@angular/core": "~22.0.8",
93
105
  "@types/node": "^26.0.0",
94
106
  "@types/react": "^19.2.0",
95
107
  "@vue/runtime-core": "^3.5.13",
96
108
  "react": "19.2.3",
109
+ "svelte": "^5.56.0",
97
110
  "typescript": "~6.0.0",
98
- "@symbiote-native/angular": "0.6.2",
99
- "@symbiote-native/engine": "0.1.7",
100
- "@symbiote-native/react": "0.2.8",
111
+ "@symbiote-native/angular": "0.7.0",
112
+ "@symbiote-native/engine": "0.2.0",
113
+ "@symbiote-native/react": "0.3.0",
114
+ "@symbiote-native/svelte": "0.2.0",
101
115
  "@symbiote-native/test-utils": "0.1.6",
102
- "@symbiote-native/vue": "0.3.8"
116
+ "@symbiote-native/vue": "0.4.0"
103
117
  },
104
118
  "scripts": {
105
119
  "typecheck": "tsc --build",
@@ -4,14 +4,4 @@
4
4
  // hooks.
5
5
  export { LocalesService } from './services/locales.service';
6
6
  export { CalendarsService } from './services/calendars.service';
7
- export {
8
- getLocales,
9
- getCalendars,
10
- addLocaleListener,
11
- addCalendarListener,
12
- Weekday,
13
- CalendarIdentifier,
14
- type Locale,
15
- type Calendar,
16
- type EventSubscription,
17
- } from '../core';
7
+ export * from '../core';
@@ -1,11 +1,9 @@
1
1
  // Hand-ported from .vendors/expo/packages/expo-localization/src/ExpoLocalization.native.ts
2
- // (sdk-57). getLocales()/getCalendars() are synchronous, JSI-bridged native calls (no await) —
3
- // the native module itself implements them as sync-bridged functions, the same constants-style
4
- // read pattern this repo already uses for expo-device's eagerly-resolved fields
2
+ // (sdk-57). getLocales()/getCalendars() are synchronous, JSI-bridged native calls (no await) -
3
+ // same constants-style read pattern as expo-device's eagerly-resolved fields
5
4
  // (packages/device/src/core/native-module.ts). One native module fans out two independent event
6
- // streams (locale settings vs calendar settings) through the same addListener, keyed by event
7
- // name — mirrors the three-event-names-on-one-addListener overload trick in
8
- // packages/battery/src/core/native-module.ts.
5
+ // streams (locale vs calendar settings) through the same addListener, keyed by event name -
6
+ // mirrors the overload trick in packages/battery/src/core/native-module.ts.
9
7
  import { type EventSubscription, requireNativeModule } from 'expo-modules-core';
10
8
  import type { Calendar, Locale } from './types';
11
9
 
@@ -5,14 +5,4 @@
5
5
 
6
6
  export { useLocales } from './hooks/use-locales';
7
7
  export { useCalendars } from './hooks/use-calendars';
8
- export {
9
- getLocales,
10
- getCalendars,
11
- addLocaleListener,
12
- addCalendarListener,
13
- Weekday,
14
- CalendarIdentifier,
15
- type Locale,
16
- type Calendar,
17
- type EventSubscription,
18
- } from '../core';
8
+ export * from '../core';
@@ -0,0 +1,9 @@
1
+ // @symbiote-native/localization/svelte: the Svelte entry over the framework-agnostic core. Locales
2
+ // and calendars each get their own lifecycle rune, matching upstream's own useLocales/
3
+ // useCalendars being two separate hooks, not one combined hook — mirrors the lifecycle-bucket
4
+ // naming convention of adapters/svelte/src/runes (never `hooks`/`composables`, those are React's
5
+ // and Vue's terms).
6
+
7
+ export { useLocales } from './runes/use-locales.svelte';
8
+ export { useCalendars } from './runes/use-calendars.svelte';
9
+ export * from '../core';
@@ -0,0 +1,29 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core — mirrors use-locales' shape exactly.
2
+ // See use-locales.svelte.ts's header for why this lives in `runes/` with a `.svelte.ts` extension
3
+ // and returns a boxed getter object instead of a bare `$state` variable.
4
+ import {
5
+ addCalendarListener,
6
+ getCalendars,
7
+ type Calendar,
8
+ type EventSubscription,
9
+ } from '../../core';
10
+
11
+ export function useCalendars(): { readonly current: Calendar[] } {
12
+ let calendars = $state<Calendar[]>(getCalendars());
13
+
14
+ $effect(() => {
15
+ // Write-only touch of `calendars` (see use-locales.svelte.ts) — the effect stays
16
+ // dependency-free and so runs once on mount, cleaning up once on unmount.
17
+ calendars = getCalendars();
18
+ const subscription: EventSubscription = addCalendarListener(() => {
19
+ calendars = getCalendars();
20
+ });
21
+ return () => subscription.remove();
22
+ });
23
+
24
+ return {
25
+ get current(): Calendar[] {
26
+ return calendars;
27
+ },
28
+ };
29
+ }
@@ -0,0 +1,30 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core (core/localization.ts). getLocales()
2
+ // is a synchronous native call, so state is seeded at call time - the `$effect` only wires the
3
+ // change listener, the twin of Vue's onMounted/onUnmounted pair.
4
+ //
5
+ // `.svelte.ts` extension: runes ($state/$effect) only work there outside a `.svelte` component;
6
+ // `runes/` is Svelte's name for the lifecycle bucket (React's `hooks/`, Vue's `composables/`).
7
+ // Returns a boxed getter, not a bare `$state`: Svelte 5 reactivity is lexically scoped to the
8
+ // declaring module and doesn't survive being returned raw from a plain function, so the caller
9
+ // reads `.current` like unwrapping Vue's `Ref` via `.value`.
10
+ import { addLocaleListener, getLocales, type EventSubscription, type Locale } from '../../core';
11
+
12
+ export function useLocales(): { readonly current: Locale[] } {
13
+ let locales = $state<Locale[]>(getLocales());
14
+
15
+ $effect(() => {
16
+ // Re-read on mount in case locales changed between this call and the effect running. This
17
+ // write never reads `locales`, so the effect has no dependency on it and fires once per mount.
18
+ locales = getLocales();
19
+ const subscription: EventSubscription = addLocaleListener(() => {
20
+ locales = getLocales();
21
+ });
22
+ return () => subscription.remove();
23
+ });
24
+
25
+ return {
26
+ get current(): Locale[] {
27
+ return locales;
28
+ },
29
+ };
30
+ }
@@ -0,0 +1,6 @@
1
+ // Pulls in svelte's ambient global declarations ($state/$effect/...) for this package's tsc
2
+ // program. adapters/svelte gets these for free because render.ts does a real value import from
3
+ // 'svelte' (any file in a program importing a module loads its ambient globals for the whole
4
+ // program); this package has no such import, so a triple-slash reference does the same job
5
+ // explicitly rather than relying on an incidental side-effect.
6
+ /// <reference types="svelte" />
package/src/vue/index.ts CHANGED
@@ -5,14 +5,4 @@
5
5
 
6
6
  export { useLocales } from './composables/use-locales';
7
7
  export { useCalendars } from './composables/use-calendars';
8
- export {
9
- getLocales,
10
- getCalendars,
11
- addLocaleListener,
12
- addCalendarListener,
13
- Weekday,
14
- CalendarIdentifier,
15
- type Locale,
16
- type Calendar,
17
- type EventSubscription,
18
- } from '../core';
8
+ export * from '../core';