@plyaz/core 1.10.1 → 1.11.1

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 (36) hide show
  1. package/dist/base/observability/DatadogAdapter.d.ts.map +1 -1
  2. package/dist/domain/example/FrontendExampleDomainService.d.ts.map +1 -1
  3. package/dist/domain/featureFlags/module.d.ts.map +1 -1
  4. package/dist/domain/files/BackendFilesDomainService.d.ts +10 -13
  5. package/dist/domain/files/BackendFilesDomainService.d.ts.map +1 -1
  6. package/dist/entry-backend.js +382 -200
  7. package/dist/entry-backend.js.map +1 -1
  8. package/dist/entry-backend.mjs +280 -98
  9. package/dist/entry-backend.mjs.map +1 -1
  10. package/dist/entry-frontend-browser.js +122 -35
  11. package/dist/entry-frontend-browser.js.map +1 -1
  12. package/dist/entry-frontend-browser.mjs +123 -33
  13. package/dist/entry-frontend-browser.mjs.map +1 -1
  14. package/dist/entry-frontend.js +122 -35
  15. package/dist/entry-frontend.js.map +1 -1
  16. package/dist/entry-frontend.mjs +123 -33
  17. package/dist/entry-frontend.mjs.map +1 -1
  18. package/dist/frontend/providers/PlyazProvider.d.ts +1 -3
  19. package/dist/frontend/providers/PlyazProvider.d.ts.map +1 -1
  20. package/dist/index.js +1339 -1134
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +1290 -1085
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/init/CoreInitializer.d.ts +31 -1
  25. package/dist/init/CoreInitializer.d.ts.map +1 -1
  26. package/dist/init/nestjs/index.js +126 -14
  27. package/dist/init/nestjs/index.js.map +1 -1
  28. package/dist/init/nestjs/index.mjs +127 -15
  29. package/dist/init/nestjs/index.mjs.map +1 -1
  30. package/dist/services/DbService.d.ts +12 -0
  31. package/dist/services/DbService.d.ts.map +1 -1
  32. package/dist/services/NotificationService.d.ts +8 -0
  33. package/dist/services/NotificationService.d.ts.map +1 -1
  34. package/dist/services/StorageService.d.ts +8 -0
  35. package/dist/services/StorageService.d.ts.map +1 -1
  36. package/package.json +3 -3
@@ -2774,6 +2774,24 @@ var Core = class _Core {
2774
2774
  */
2775
2775
  this._rootStore = null;
2776
2776
  }
2777
+ static {
2778
+ /**
2779
+ * Injected store hook for frontend (set via setRootStoreHook before initialize).
2780
+ * This is used instead of directly importing from @plyaz/store to prevent
2781
+ * duplicate store instances when bundlers create multiple module copies.
2782
+ */
2783
+ this._injectedStoreHook = null;
2784
+ }
2785
+ /**
2786
+ * Set the root store hook for frontend use.
2787
+ * Must be called before Core.initialize() when running in browser.
2788
+ * PlyazProvider calls this automatically with the store prop.
2789
+ *
2790
+ * @param store - The useRootStore hook from @plyaz/store
2791
+ */
2792
+ static setRootStoreHook(store) {
2793
+ _Core._injectedStoreHook = store;
2794
+ }
2777
2795
  /**
2778
2796
  * Setup environment and context
2779
2797
  */
@@ -3684,8 +3702,14 @@ var Core = class _Core {
3684
3702
  static async initializeRootStore(config, verbose) {
3685
3703
  const isFrontend = typeof window !== "undefined";
3686
3704
  if (isFrontend) {
3687
- _Core.log("Using frontend root store (Zustand)", verbose);
3688
- _Core._rootStore = store.useRootStore;
3705
+ if (!_Core._injectedStoreHook) {
3706
+ throw new errors.CorePackageError(
3707
+ "Root store hook not set. Call Core.setRootStoreHook(useRootStore) before Core.initialize(), or use PlyazProvider with the store prop: <PlyazProvider store={useRootStore} ...>",
3708
+ types.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
3709
+ );
3710
+ }
3711
+ _Core.log("Using frontend root store (Zustand) - injected via setRootStoreHook", verbose);
3712
+ _Core._rootStore = _Core._injectedStoreHook;
3689
3713
  } else {
3690
3714
  _Core.log("Creating backend composite store (in-memory)", verbose);
3691
3715
  const ServerErrorMiddleware = getCoreDependency("ServerErrorMiddleware");
@@ -3794,26 +3818,76 @@ var Core = class _Core {
3794
3818
  errorStore,
3795
3819
  _Core.buildErrorHandlerConfig(_Core._errorConfig)
3796
3820
  );
3821
+ _Core.setupErrorEventSubscription(verbose);
3822
+ _Core.setupErrorStoreSubscription(verbose);
3823
+ _Core.log("Global error handler initialized with CoreEventManager integration", verbose);
3824
+ if (_Core._errorConfig.httpHandler !== false) {
3825
+ await _Core.createHttpErrorHandler(_Core._errorConfig, verbose);
3826
+ }
3827
+ }
3828
+ /**
3829
+ * Log serialized errors with full details.
3830
+ */
3831
+ static logErrors(errors, prefix = "ErrorStore") {
3832
+ for (const err of errors) {
3833
+ _Core.logger.error(`[${prefix}] ${err.code}: ${err.message}`, {
3834
+ id: err.id,
3835
+ code: err.code,
3836
+ message: err.message,
3837
+ category: err.category,
3838
+ source: err.source,
3839
+ status: err.status,
3840
+ isRetryable: err.isRetryable,
3841
+ context: err.context,
3842
+ timestamp: err.timestamp
3843
+ });
3844
+ }
3845
+ }
3846
+ /**
3847
+ * Setup SYSTEM.ERROR event subscription for error store updates.
3848
+ * Backend: Also logs errors with full details.
3849
+ * Frontend: Only updates store (logging handled by store subscription).
3850
+ */
3851
+ static setupErrorEventSubscription(verbose) {
3852
+ const isBackend = types.BACKEND_RUNTIMES.includes(_Core._coreServices.runtime);
3797
3853
  const errorEventCleanup = CoreEventManager.on(
3798
3854
  core.CORE_EVENTS.SYSTEM.ERROR,
3799
3855
  (event) => {
3800
3856
  if (!_Core._rootStore) return;
3801
3857
  try {
3802
3858
  const { errors } = event.data;
3803
- if (errors && errors.length > 0) {
3804
- _Core._rootStore.getState().errors.addErrors(errors);
3805
- _Core.log(`Added ${errors.length} error(s) to store`, verbose);
3806
- }
3859
+ if (!errors || errors.length === 0) return;
3860
+ _Core._rootStore.getState().errors.addErrors(errors);
3861
+ if (isBackend) _Core.logErrors(errors);
3862
+ _Core.log(`Added ${errors.length} error(s) to store`, verbose);
3807
3863
  } catch (e) {
3808
3864
  _Core.logger.error("Failed to handle error event", { error: e });
3809
3865
  }
3810
3866
  }
3811
3867
  );
3812
3868
  _Core._eventCleanupFns.push(errorEventCleanup);
3813
- _Core.log("Global error handler initialized with CoreEventManager integration", verbose);
3814
- if (_Core._errorConfig.httpHandler !== false) {
3815
- await _Core.createHttpErrorHandler(_Core._errorConfig, verbose);
3816
- }
3869
+ }
3870
+ /**
3871
+ * Setup error store subscription for frontend logging.
3872
+ * Logs new errors when they're added to the store.
3873
+ * Only active for non-backend runtimes (browser, nextjs, nuxt, edge).
3874
+ */
3875
+ static setupErrorStoreSubscription(verbose) {
3876
+ const isFrontend = !types.BACKEND_RUNTIMES.includes(_Core._coreServices.runtime);
3877
+ if (!isFrontend || !_Core._rootStore) return;
3878
+ let prevErrorCount = 0;
3879
+ const storeUnsubscribe = _Core._rootStore.subscribe((state) => {
3880
+ const currentCount = state.errors.errorCount;
3881
+ if (currentCount <= prevErrorCount) {
3882
+ prevErrorCount = currentCount;
3883
+ return;
3884
+ }
3885
+ const newErrors = state.errors.errors.slice(0, currentCount - prevErrorCount);
3886
+ _Core.logErrors(newErrors, "ErrorStore:FE");
3887
+ prevErrorCount = currentCount;
3888
+ });
3889
+ _Core._eventCleanupFns.push(storeUnsubscribe);
3890
+ _Core.log("Error store subscription initialized for frontend", verbose);
3817
3891
  }
3818
3892
  /**
3819
3893
  * Create HTTP error handler based on detected runtime.
@@ -6777,7 +6851,7 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6777
6851
  // Constructor
6778
6852
  // ─────────────────────────────────────────────────────────────────────────
6779
6853
  constructor(config = {}, options) {
6780
- const apiBasePath = config.apiBasePath || "/api/examples";
6854
+ const apiBasePath = config.apiBasePath || "";
6781
6855
  super({
6782
6856
  serviceName: "ExampleFrontendService",
6783
6857
  supportedRuntimes: ["frontend"],
@@ -6802,20 +6876,20 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6802
6876
  // Note: Use relative paths since apiClient.baseURL is already set to apiBasePath
6803
6877
  fetchers: {
6804
6878
  fetchAll: /* @__PURE__ */ __name(async (query) => {
6805
- return this.apiClient.get("", { params: query });
6879
+ return this.apiClient.get("/examples", { params: query });
6806
6880
  }, "fetchAll"),
6807
6881
  fetchById: /* @__PURE__ */ __name(async (id) => {
6808
- return this.apiClient.get(`/${id}`);
6882
+ return this.apiClient.get(`/examples/${id}`);
6809
6883
  }, "fetchById"),
6810
6884
  create: /* @__PURE__ */ __name(async (data) => {
6811
- return this.apiClient.post("", data);
6885
+ return this.apiClient.post("/examples", data);
6812
6886
  }, "create"),
6813
6887
  update: /* @__PURE__ */ __name(async (payload) => {
6814
6888
  const { id, data } = payload;
6815
- return this.apiClient.patch(`/${id}`, data);
6889
+ return this.apiClient.patch(`/examples/${id}`, data);
6816
6890
  }, "update"),
6817
6891
  delete: /* @__PURE__ */ __name(async (id) => {
6818
- return this.apiClient.delete(`/${id}`);
6892
+ return this.apiClient.delete(`/examples/${id}`);
6819
6893
  }, "delete")
6820
6894
  }
6821
6895
  // Store handlers - customize how data syncs to store
@@ -6883,7 +6957,7 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
6883
6957
  // The ?? operator only falls through on null/undefined, not empty strings.
6884
6958
  // An empty string is not a valid API path, so we treat it as "not provided" and fall through to default.
6885
6959
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
6886
- apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || "/api/examples"
6960
+ apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || ""
6887
6961
  };
6888
6962
  const service = new _FrontendExampleDomainService(mergedConfig, options);
6889
6963
  if (mergedConfig.autoFetch) {
@@ -7044,7 +7118,10 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
7044
7118
  const response = await this.apiClient.post(endpoint, data);
7045
7119
  if (!this.isResponseSuccess(response)) {
7046
7120
  const error = this.extractResponseError(response);
7047
- throw new Error(`Failed to send email: ${JSON.stringify(error)}`);
7121
+ throw new errors.CorePackageError(
7122
+ `Failed to send email: ${JSON.stringify(error)}`,
7123
+ types.ERROR_CODES.CORE_OPERATION_FAILED
7124
+ );
7048
7125
  }
7049
7126
  const result = this.unwrapResponseData(response.data);
7050
7127
  CoreEventManager.emit(`${this.eventPrefix}:email:sent`, { result });
@@ -7255,7 +7332,7 @@ var FilesMapper = new FilesMapperClass();
7255
7332
  var logger4 = new logger$1.PackageLogger({ packageName: "core", service: "FrontendFilesDomainService" });
7256
7333
  var FrontendFilesDomainService = class _FrontendFilesDomainService extends BaseFrontendDomainService {
7257
7334
  constructor(config = {}, options) {
7258
- const apiBasePath = config.apiBasePath || "/api";
7335
+ const apiBasePath = config.apiBasePath || "";
7259
7336
  super({
7260
7337
  serviceName: "FrontendFilesDomainService",
7261
7338
  supportedRuntimes: ["frontend"],
@@ -7318,7 +7395,7 @@ var FrontendFilesDomainService = class _FrontendFilesDomainService extends BaseF
7318
7395
  // The ?? operator only falls through on null/undefined, not empty strings.
7319
7396
  // An empty string is not a valid API path, so we treat it as "not provided" and fall through to default.
7320
7397
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
7321
- apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || "/api"
7398
+ apiBasePath: config.apiBasePath || options?.apiClient?.options?.baseURL || ""
7322
7399
  };
7323
7400
  return new _FrontendFilesDomainService(mergedConfig, options);
7324
7401
  }
@@ -9058,22 +9135,27 @@ async function initializeCore(config) {
9058
9135
  });
9059
9136
  }
9060
9137
  __name(initializeCore, "initializeCore");
9061
- function createStoreRegistry() {
9138
+ function createStoreRegistry(store) {
9062
9139
  return {
9063
9140
  getStore(key) {
9064
- const state = store.useRootStore.getState();
9141
+ const state = store.getState();
9065
9142
  if (!state) {
9066
9143
  logger5.warn(
9067
9144
  "Store state is undefined - store may not be hydrated yet. This can cause side effects if called during SSR or before initialization."
9068
9145
  );
9069
9146
  return void 0;
9070
9147
  }
9071
- return state[key];
9148
+ const slice = state[key];
9149
+ logger5.debug(`[StoreRegistry] getStore('${key}')`, {
9150
+ hasSlice: !!slice,
9151
+ sliceKeys: slice ? Object.keys(slice) : []
9152
+ });
9153
+ return slice;
9072
9154
  }
9073
9155
  };
9074
9156
  }
9075
9157
  __name(createStoreRegistry, "createStoreRegistry");
9076
- async function initializeServices(config) {
9158
+ async function initializeServices(config, store) {
9077
9159
  if (!config.services || config.services.length === 0) return;
9078
9160
  if (config.verbose) {
9079
9161
  globalThis.console.log("[PlyazProvider] Initializing domain services...");
@@ -9085,7 +9167,7 @@ async function initializeServices(config) {
9085
9167
  observability: config.observability,
9086
9168
  services: config.services,
9087
9169
  // Provide store registry for injecting stores into services
9088
- stores: createStoreRegistry()
9170
+ stores: createStoreRegistry(store)
9089
9171
  });
9090
9172
  if (config.verbose) {
9091
9173
  globalThis.console.log(
@@ -9122,6 +9204,7 @@ function createServicesObject(config, featureFlagStore) {
9122
9204
  __name(createServicesObject, "createServicesObject");
9123
9205
  function PlyazProvider({
9124
9206
  children,
9207
+ store,
9125
9208
  config,
9126
9209
  loading,
9127
9210
  error: errorComponent,
@@ -9135,8 +9218,9 @@ function PlyazProvider({
9135
9218
  const initialize = react.useCallback(async () => {
9136
9219
  try {
9137
9220
  setError(null);
9221
+ Core.setRootStoreHook(store);
9138
9222
  await initializeCore(config);
9139
- await initializeServices(config);
9223
+ await initializeServices(config, store);
9140
9224
  await initializeFeatureFlags(featureFlagStore);
9141
9225
  setIsReady(true);
9142
9226
  onReady?.(createServicesObject(config, featureFlagStore));
@@ -9146,7 +9230,7 @@ function PlyazProvider({
9146
9230
  onError?.(initError);
9147
9231
  globalThis.console.error("[PlyazProvider] Initialization failed:", initError);
9148
9232
  }
9149
- }, [config, featureFlagStore, onReady, onError]);
9233
+ }, [config, store, featureFlagStore, onReady, onError]);
9150
9234
  const reinitialize = react.useCallback(async () => {
9151
9235
  setIsReady(false);
9152
9236
  ServiceRegistry.disposeAll();
@@ -9195,8 +9279,9 @@ __name(PlyazProvider, "PlyazProvider");
9195
9279
  function usePlyaz() {
9196
9280
  const context = react.useContext(PlyazContext);
9197
9281
  if (!context) {
9198
- throw new Error(
9199
- "usePlyaz must be used within a PlyazProvider. Wrap your app with <PlyazProvider config={...}>...</PlyazProvider>"
9282
+ throw new errors.CorePackageError(
9283
+ "usePlyaz must be used within a PlyazProvider. Wrap your app with <PlyazProvider config={...}>...</PlyazProvider>",
9284
+ types.ERROR_CODES.CORE_PROVIDER_NOT_FOUND
9200
9285
  );
9201
9286
  }
9202
9287
  return context;
@@ -9205,7 +9290,10 @@ __name(usePlyaz, "usePlyaz");
9205
9290
  function useApi() {
9206
9291
  const { api, isReady } = usePlyaz();
9207
9292
  if (!isReady || !api) {
9208
- throw new Error("API client is not ready. Make sure PlyazProvider has finished initializing.");
9293
+ throw new errors.CorePackageError(
9294
+ "API client is not ready. Make sure PlyazProvider has finished initializing.",
9295
+ types.ERROR_CODES.CORE_PROVIDER_INITIALIZATION_FAILED
9296
+ );
9209
9297
  }
9210
9298
  return api;
9211
9299
  }
@@ -9248,7 +9336,10 @@ __name(useEnvironment, "useEnvironment");
9248
9336
  function useService(key) {
9249
9337
  const { getService, isReady } = usePlyaz();
9250
9338
  if (!isReady) {
9251
- throw new Error(`PlyazProvider not ready. Cannot get service '${key}'.`);
9339
+ throw new errors.CorePackageError(
9340
+ `PlyazProvider not ready. Cannot get service '${key}'.`,
9341
+ types.ERROR_CODES.CORE_PROVIDER_INITIALIZATION_FAILED
9342
+ );
9252
9343
  }
9253
9344
  return react.useMemo(() => getService(key), [getService, key]);
9254
9345
  }
@@ -9371,10 +9462,6 @@ function createFeatureFlagStoreConfig(options) {
9371
9462
  }
9372
9463
  __name(createFeatureFlagStoreConfig, "createFeatureFlagStoreConfig");
9373
9464
 
9374
- Object.defineProperty(exports, "useRootStore", {
9375
- enumerable: true,
9376
- get: function () { return store.useRootStore; }
9377
- });
9378
9465
  exports.ApiClientService = ApiClientService;
9379
9466
  exports.ApiProvider = ApiProvider;
9380
9467
  exports.BaseDomainService = BaseDomainService;