@plyaz/core 1.8.1 → 1.8.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.
@@ -2257,10 +2257,16 @@ var ServiceRegistry = class _ServiceRegistry {
2257
2257
  return initPromise;
2258
2258
  }
2259
2259
  /** Build stores for service injection */
2260
- static buildStoresForService(config) {
2260
+ // eslint-disable-next-line complexity
2261
+ static buildStoresForService(config, entry) {
2261
2262
  const allKeys = /* @__PURE__ */ new Set();
2262
2263
  if (config.store) {
2263
2264
  allKeys.add(config.store);
2265
+ } else if ("primaryStoreKey" in entry.service && typeof entry.service.primaryStoreKey === "string") {
2266
+ allKeys.add(entry.service.primaryStoreKey);
2267
+ _ServiceRegistry.logger.debug(
2268
+ `Auto-resolved store key '${entry.service.primaryStoreKey}' from service class`
2269
+ );
2264
2270
  }
2265
2271
  if (config.readStores) {
2266
2272
  config.readStores.forEach((key) => allKeys.add(key));
@@ -2298,7 +2304,7 @@ var ServiceRegistry = class _ServiceRegistry {
2298
2304
  const observability = _ServiceRegistry.buildObservabilityConfig(config, entry);
2299
2305
  const storage = await _ServiceRegistry.buildStorageConfig(config, entry);
2300
2306
  const notifications = await _ServiceRegistry.buildNotificationsConfig(config, entry);
2301
- const stores = _ServiceRegistry.buildStoresForService(config);
2307
+ const stores = _ServiceRegistry.buildStoresForService(config, entry);
2302
2308
  let observabilityInstance = observability?.instance;
2303
2309
  if (observability?.dedicated && observability.config) {
2304
2310
  observabilityInstance = await _ServiceRegistry.createDedicatedObservability(
@@ -3827,6 +3833,13 @@ var Core = class _Core {
3827
3833
  /** Create fetch flags function */
3828
3834
  static createFetchFlagsFn(config, verbose) {
3829
3835
  return async () => {
3836
+ if (config?.provider !== "api") {
3837
+ _Core.log(
3838
+ `Feature flags using ${config?.provider ?? "default"} provider (no API fetch)`,
3839
+ verbose
3840
+ );
3841
+ return config?.defaults ?? {};
3842
+ }
3830
3843
  try {
3831
3844
  const client = ApiClientService.getClient();
3832
3845
  const endpoint = config?.apiEndpoint ?? "/feature-flags";
@@ -3846,6 +3859,7 @@ var Core = class _Core {
3846
3859
  /**
3847
3860
  * Initialize feature flags slice within root store
3848
3861
  */
3862
+ // eslint-disable-next-line complexity
3849
3863
  static async initializeFeatureFlags(config, verbose) {
3850
3864
  if (config?.enabled === false) {
3851
3865
  _Core.log("Feature flags disabled by configuration", verbose);
@@ -3858,11 +3872,16 @@ var Core = class _Core {
3858
3872
  );
3859
3873
  }
3860
3874
  _Core._flagConfig = config ?? {};
3861
- _Core.log("Initializing feature flags from root store...", verbose);
3875
+ const isApiProvider = config?.provider === "api";
3876
+ _Core.log(
3877
+ `Initializing feature flags from root store (provider: ${config?.provider ?? "default"})...`,
3878
+ verbose
3879
+ );
3862
3880
  const state = _Core._rootStore.getState();
3863
3881
  await state.featureFlags.initialize({
3864
3882
  defaults: _Core._flagConfig.defaults,
3865
- polling: _Core._flagConfig.polling,
3883
+ // Only enable polling for API provider
3884
+ polling: isApiProvider ? _Core._flagConfig.polling : void 0,
3866
3885
  fetchFn: _Core.createFetchFlagsFn(_Core._flagConfig, verbose),
3867
3886
  onFlagChange: _Core._flagConfig.onFlagChange,
3868
3887
  onError: _Core._flagConfig.onError
@@ -4269,13 +4288,14 @@ var BaseDomainService = class {
4269
4288
  );
4270
4289
  }
4271
4290
  };
4272
- var BaseFrontendDomainService = class extends BaseDomainService {
4291
+ var BaseFrontendDomainService = class _BaseFrontendDomainService extends BaseDomainService {
4273
4292
  // ─────────────────────────────────────────────────────────────────────────
4274
4293
  // Constructor
4275
4294
  // ─────────────────────────────────────────────────────────────────────────
4276
4295
  // eslint-disable-next-line complexity
4277
4296
  constructor(config) {
4278
- super(config);
4297
+ const resolvedConfig = _BaseFrontendDomainService.resolveApiClientConfig(config);
4298
+ super(resolvedConfig);
4279
4299
  // ─────────────────────────────────────────────────────────────────────────
4280
4300
  // Store Properties
4281
4301
  // ─────────────────────────────────────────────────────────────────────────
@@ -4301,6 +4321,11 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4301
4321
  const serviceConfig = config.serviceConfig;
4302
4322
  if (serviceConfig.store !== void 0) {
4303
4323
  this.primaryStoreKey = serviceConfig.store;
4324
+ } else {
4325
+ const staticKey = this.constructor.primaryStoreKey;
4326
+ if (staticKey) {
4327
+ this.primaryStoreKey = staticKey;
4328
+ }
4304
4329
  }
4305
4330
  if (serviceConfig.readStores !== void 0) {
4306
4331
  this.readStoreKeys = Array.from(
@@ -4319,9 +4344,12 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4319
4344
  this._primaryStore = primaryStore;
4320
4345
  this.logDebug(`Connected primary store: '${this.primaryStoreKey}'`);
4321
4346
  } else {
4322
- this.logWarn(
4323
- `Primary store '${this.primaryStoreKey}' not found. Store mutations (setData/updateData/setLoading) will be disabled. Configure stores in PlyazProvider to enable store integration.`
4324
- );
4347
+ const isServer = typeof globalThis.window === "undefined";
4348
+ if (!isServer) {
4349
+ this.logWarn(
4350
+ `Primary store '${this.primaryStoreKey}' not found. Store mutations (setData/updateData/setLoading) will be disabled. Configure stores in PlyazProvider to enable store integration.`
4351
+ );
4352
+ }
4325
4353
  }
4326
4354
  }
4327
4355
  for (const key of this.readStoreKeys) {
@@ -4346,6 +4374,66 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4346
4374
  static {
4347
4375
  __name(this, "BaseFrontendDomainService");
4348
4376
  }
4377
+ /**
4378
+ * Auto-resolve apiClientConfig from serviceConfig.apiBasePath if not explicitly provided.
4379
+ * This reduces boilerplate in child services - they only need to set apiBasePath in config.
4380
+ *
4381
+ * Priority:
4382
+ * 1. Explicit apiClientConfig.baseURL (full control)
4383
+ * 2. serviceConfig.apiBasePath (auto-constructed, merged with injected options)
4384
+ * 3. undefined (no API client)
4385
+ *
4386
+ * When auto-constructing, merges injected API options (headers, timeout, etc.)
4387
+ * with the service's apiBasePath as baseURL.
4388
+ */
4389
+ static resolveApiClientConfig(config) {
4390
+ if (config.apiClientConfig?.baseURL) {
4391
+ return config;
4392
+ }
4393
+ const apiBasePath = config.serviceConfig.apiBasePath;
4394
+ if (apiBasePath) {
4395
+ const injectedOptions = config.injected?.api ? {} : config.apiClientConfig ?? {};
4396
+ return {
4397
+ ...config,
4398
+ apiClientConfig: {
4399
+ ...injectedOptions,
4400
+ baseURL: apiBasePath
4401
+ // Service's apiBasePath always takes precedence
4402
+ }
4403
+ };
4404
+ }
4405
+ return config;
4406
+ }
4407
+ /**
4408
+ * Initialize service and wait for API client to be ready.
4409
+ * Call this in child service's static create() method after constructing the instance.
4410
+ *
4411
+ * @param service - The service instance to initialize
4412
+ * @returns The initialized service (same instance, for chaining)
4413
+ *
4414
+ * @example
4415
+ * ```typescript
4416
+ * static async create(config, options): Promise<MyService> {
4417
+ * const service = new MyService(config, options);
4418
+ * return this.initializeService(service);
4419
+ * }
4420
+ * ```
4421
+ */
4422
+ static async initializeService(service) {
4423
+ await service.ensureApiClientInitialized();
4424
+ return service;
4425
+ }
4426
+ /**
4427
+ * Ensure service is ready for operations.
4428
+ * Checks enabled/available status AND waits for API client initialization.
4429
+ * Call this at the start of all CRUD methods.
4430
+ *
4431
+ * @throws CorePackageError if service is not enabled or available
4432
+ */
4433
+ async ensureReady() {
4434
+ this.assertReady();
4435
+ await this.ensureApiClientInitialized();
4436
+ }
4349
4437
  // ─────────────────────────────────────────────────────────────────────────
4350
4438
  // Store Management (Public API)
4351
4439
  // ─────────────────────────────────────────────────────────────────────────
@@ -4818,7 +4906,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4818
4906
  */
4819
4907
  // eslint-disable-next-line complexity
4820
4908
  async fetchAll(query, options) {
4821
- this.assertReady();
4909
+ await this.ensureReady();
4822
4910
  const startTime = Date.now();
4823
4911
  if (!this.config.fetchers?.fetchAll) {
4824
4912
  throw new errors.CorePackageError(
@@ -4903,7 +4991,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4903
4991
  */
4904
4992
  // eslint-disable-next-line complexity
4905
4993
  async fetchById(id, options) {
4906
- this.assertReady();
4994
+ await this.ensureReady();
4907
4995
  const startTime = Date.now();
4908
4996
  if (!this.config.fetchers?.fetchById) {
4909
4997
  throw new errors.CorePackageError(
@@ -4964,7 +5052,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
4964
5052
  */
4965
5053
  // eslint-disable-next-line complexity, max-lines-per-function
4966
5054
  async create(data, options) {
4967
- this.assertReady();
5055
+ await this.ensureReady();
4968
5056
  const startTime = Date.now();
4969
5057
  if (!this.config.fetchers?.create) {
4970
5058
  throw new errors.CorePackageError(
@@ -5057,7 +5145,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
5057
5145
  */
5058
5146
  // eslint-disable-next-line complexity, max-lines-per-function
5059
5147
  async update(id, data, options) {
5060
- this.assertReady();
5148
+ await this.ensureReady();
5061
5149
  const startTime = Date.now();
5062
5150
  if (!this.config.fetchers?.update) {
5063
5151
  throw new errors.CorePackageError(
@@ -5146,7 +5234,7 @@ var BaseFrontendDomainService = class extends BaseDomainService {
5146
5234
  */
5147
5235
  // eslint-disable-next-line complexity
5148
5236
  async delete(id, options) {
5149
- this.assertReady();
5237
+ await this.ensureReady();
5150
5238
  const startTime = Date.now();
5151
5239
  if (!this.config.fetchers?.delete) {
5152
5240
  throw new errors.CorePackageError(
@@ -6117,14 +6205,11 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6117
6205
  // ─────────────────────────────────────────────────────────────────────────
6118
6206
  // Constructor
6119
6207
  // ─────────────────────────────────────────────────────────────────────────
6120
- // eslint-disable-next-line complexity
6121
6208
  constructor(config = {}, options) {
6122
6209
  const apiBasePath = config.apiBasePath ?? "/api/examples";
6123
6210
  super({
6124
6211
  serviceName: "ExampleFrontendService",
6125
6212
  supportedRuntimes: ["frontend"],
6126
- // API client config - uses injected options or creates from apiBasePath
6127
- apiClientConfig: options?.apiClient?.options ?? { baseURL: apiBasePath },
6128
6213
  serviceConfig: {
6129
6214
  enabled: true,
6130
6215
  apiBasePath,
@@ -6188,10 +6273,6 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6188
6273
  * Required by BaseFrontendDomainService
6189
6274
  */
6190
6275
  this.eventPrefix = "example";
6191
- /**
6192
- * Primary store key - the store this service can mutate
6193
- */
6194
- this.primaryStoreKey = store.STORE_KEYS.EXAMPLE;
6195
6276
  /**
6196
6277
  * Read-only store keys - inherits error and featureFlags from base
6197
6278
  * No need to redeclare them - they're always included by default
@@ -6214,6 +6295,14 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6214
6295
  // ─────────────────────────────────────────────────────────────────────────
6215
6296
  this.serviceKey = core.SERVICE_KEYS.EXAMPLE_FRONTEND;
6216
6297
  }
6298
+ static {
6299
+ /**
6300
+ * Primary store key for this service.
6301
+ * Used by ServiceRegistry to auto-inject the store if not specified in config.
6302
+ * Also used by base class constructor to set instance primaryStoreKey.
6303
+ */
6304
+ this.primaryStoreKey = store.STORE_KEYS.EXAMPLE;
6305
+ }
6217
6306
  /**
6218
6307
  * Factory method for ServiceRegistry auto-initialization.
6219
6308
  * Creates and initializes the service instance.