Skip to content

Commit db17fe9

Browse files
committed
[FSSDK-10992] add universal entrypoint
1 parent cf595be commit db17fe9

File tree

9 files changed

+308
-6
lines changed

9 files changed

+308
-6
lines changed

lib/entrypoint.universal.test-d.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { expectTypeOf } from 'vitest';
18+
19+
import * as universal from './index.universal';
20+
21+
type WithoutReadonly<T> = { -readonly [P in keyof T]: T[P] };
22+
23+
const universalEntrypoint: WithoutReadonly<typeof universal> = universal;
24+
25+
import {
26+
Config,
27+
Client,
28+
StaticConfigManagerConfig,
29+
OpaqueConfigManager,
30+
EventDispatcher,
31+
OpaqueEventProcessor,
32+
OpaqueLevelPreset,
33+
LoggerConfig,
34+
OpaqueLogger,
35+
ErrorHandler,
36+
OpaqueErrorNotifier,
37+
} from './export_types';
38+
39+
import { UniversalPollingConfigManagerConfig } from './project_config/config_manager_factory.universal';
40+
import { RequestHandler } from './utils/http_request_handler/http';
41+
import { UniversalBatchEventProcessorOptions } from './event_processor/event_processor_factory.universal';
42+
import {
43+
DECISION_SOURCES,
44+
DECISION_NOTIFICATION_TYPES,
45+
NOTIFICATION_TYPES,
46+
} from './utils/enums';
47+
48+
import { LogLevel } from './logging/logger';
49+
50+
import { OptimizelyDecideOption } from './shared_types';
51+
52+
export type UniversalEntrypoint = {
53+
// client factory
54+
createInstance: (config: Config) => Client | null;
55+
56+
// config manager related exports
57+
createStaticProjectConfigManager: (config: StaticConfigManagerConfig) => OpaqueConfigManager;
58+
createPollingProjectConfigManager: (config: UniversalPollingConfigManagerConfig) => OpaqueConfigManager;
59+
60+
// event processor related exports
61+
createEventDispatcher: (requestHandler: RequestHandler) => EventDispatcher;
62+
createForwardingEventProcessor: (eventDispatcher: EventDispatcher) => OpaqueEventProcessor;
63+
createBatchEventProcessor: (options: UniversalBatchEventProcessorOptions) => OpaqueEventProcessor;
64+
65+
// TODO: odp manager related exports
66+
// createOdpManager: (options: OdpManagerOptions) => OpaqueOdpManager;
67+
68+
// TODO: vuid manager related exports
69+
// createVuidManager: (options: VuidManagerOptions) => OpaqueVuidManager;
70+
71+
// logger related exports
72+
LogLevel: typeof LogLevel;
73+
DebugLog: OpaqueLevelPreset,
74+
InfoLog: OpaqueLevelPreset,
75+
WarnLog: OpaqueLevelPreset,
76+
ErrorLog: OpaqueLevelPreset,
77+
createLogger: (config: LoggerConfig) => OpaqueLogger;
78+
79+
// error related exports
80+
createErrorNotifier: (errorHandler: ErrorHandler) => OpaqueErrorNotifier;
81+
82+
// enums
83+
DECISION_SOURCES: typeof DECISION_SOURCES;
84+
DECISION_NOTIFICATION_TYPES: typeof DECISION_NOTIFICATION_TYPES;
85+
NOTIFICATION_TYPES: typeof NOTIFICATION_TYPES;
86+
87+
// decide options
88+
OptimizelyDecideOption: typeof OptimizelyDecideOption;
89+
90+
// client engine
91+
clientEngine: string;
92+
}
93+
94+
95+
expectTypeOf(universalEntrypoint).toEqualTypeOf<UniversalEntrypoint>();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { RequestHandler } from '../../utils/http_request_handler/http';
2+
import { DefaultEventDispatcher } from './default_dispatcher';
3+
import { EventDispatcher } from './event_dispatcher';
4+
5+
export const createEventDispatcher = (requestHander: RequestHandler): EventDispatcher => {
6+
return new DefaultEventDispatcher(requestHander);
7+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { getForwardingEventProcessor } from './forwarding_event_processor';
18+
import { EventDispatcher } from './event_dispatcher/event_dispatcher';
19+
20+
import {
21+
getOpaqueBatchEventProcessor,
22+
BatchEventProcessorOptions,
23+
OpaqueEventProcessor,
24+
wrapEventProcessor,
25+
getPrefixEventStore,
26+
} from './event_processor_factory';
27+
28+
import { FAILED_EVENT_RETRY_INTERVAL } from './event_processor_factory';
29+
30+
export const createForwardingEventProcessor = (
31+
eventDispatcher: EventDispatcher
32+
): OpaqueEventProcessor => {
33+
return wrapEventProcessor(getForwardingEventProcessor(eventDispatcher));
34+
};
35+
36+
export type UniversalBatchEventProcessorOptions = Omit<BatchEventProcessorOptions, 'eventDispatcher'> & {
37+
eventDispatcher: EventDispatcher;
38+
}
39+
40+
export const createBatchEventProcessor = (
41+
options: UniversalBatchEventProcessorOptions
42+
): OpaqueEventProcessor => {
43+
const eventStore = options.eventStore ? getPrefixEventStore(options.eventStore) : undefined;
44+
45+
return getOpaqueBatchEventProcessor({
46+
eventDispatcher: options.eventDispatcher,
47+
closingEventDispatcher: options.closingEventDispatcher,
48+
flushInterval: options.flushInterval,
49+
batchSize: options.batchSize,
50+
retryOptions: {
51+
maxRetries: 5,
52+
},
53+
failedEventRetryInterval: FAILED_EVENT_RETRY_INTERVAL,
54+
eventStore: eventStore,
55+
});
56+
};

lib/export_types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ export type {
6767
NotificationPayload,
6868
} from './notification_center/type';
6969

70-
export type { OptimizelyDecideOption } from './shared_types';
71-
7270
export type {
7371
UserAttributeValue,
7472
UserAttributes,

lib/index.lite.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

lib/index.universal.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { Client, Config } from './shared_types';
17+
import { getOptimizelyInstance } from './client_factory';
18+
import { JAVASCRIPT_CLIENT_ENGINE } from './utils/enums';
19+
20+
/**
21+
* Creates an instance of the Optimizely class
22+
* @param {Config} config
23+
* @return {Client|null} the Optimizely client object
24+
* null on error
25+
*/
26+
export const createInstance = function(config: Config): Client | null {
27+
return getOptimizelyInstance(config);
28+
};
29+
30+
export { createEventDispatcher } from './event_processor/event_dispatcher/event_dispatcher_factory';
31+
32+
export { createPollingProjectConfigManager } from './project_config/config_manager_factory.universal';
33+
34+
export { createForwardingEventProcessor, createBatchEventProcessor } from './event_processor/event_processor_factory.universal';
35+
36+
// TODO: decide on universal odp manager factory interface
37+
// export { createOdpManager } from './odp/odp_manager_factory.node';
38+
// export { createVuidManager } from './vuid/vuid_manager_factory.node';
39+
40+
export * from './common_exports';
41+
42+
export const clientEngine: string = JAVASCRIPT_CLIENT_ENGINE;
43+
44+
// type exports
45+
export type { RequestHandler } from './utils/http_request_handler/http';
46+
47+
// config manager related types
48+
export type {
49+
StaticConfigManagerConfig,
50+
OpaqueConfigManager,
51+
} from './project_config/config_manager_factory';
52+
53+
export type { UniversalPollingConfigManagerConfig } from './project_config/config_manager_factory.universal';
54+
55+
// event processor related types
56+
export type {
57+
LogEvent,
58+
EventDispatcherResponse,
59+
EventDispatcher,
60+
} from './event_processor/event_dispatcher/event_dispatcher';
61+
62+
export type { UniversalBatchEventProcessorOptions } from './event_processor/event_processor_factory.universal';
63+
64+
export type {
65+
OpaqueEventProcessor,
66+
} from './event_processor/event_processor_factory';
67+
68+
// Logger related types
69+
export type {
70+
LogHandler,
71+
} from './logging/logger';
72+
73+
export type {
74+
OpaqueLevelPreset,
75+
LoggerConfig,
76+
OpaqueLogger,
77+
} from './logging/logger_factory';
78+
79+
// Error related types
80+
export type { ErrorHandler } from './error/error_handler';
81+
export type { OpaqueErrorNotifier } from './error/error_notifier_factory';
82+
83+
export type { Cache } from './utils/cache/cache';
84+
85+
export type {
86+
NotificationType,
87+
NotificationPayload,
88+
} from './notification_center/type';
89+
90+
export type {
91+
UserAttributeValue,
92+
UserAttributes,
93+
OptimizelyConfig,
94+
FeatureVariableValue,
95+
OptimizelyVariable,
96+
OptimizelyVariation,
97+
OptimizelyExperiment,
98+
OptimizelyFeature,
99+
OptimizelyDecisionContext,
100+
OptimizelyForcedDecision,
101+
EventTags,
102+
Event,
103+
DatafileOptions,
104+
UserProfileService,
105+
UserProfile,
106+
ListenerPayload,
107+
OptimizelyDecision,
108+
OptimizelyUserContext,
109+
Config,
110+
Client,
111+
ActivateListenerPayload,
112+
TrackListenerPayload,
113+
NotificationCenter,
114+
OptimizelySegmentOption,
115+
} from './shared_types';
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright 2025, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { getOpaquePollingConfigManager, OpaqueConfigManager, PollingConfigManagerConfig } from "./config_manager_factory";
18+
import { NodeRequestHandler } from "../utils/http_request_handler/request_handler.node";
19+
import { ProjectConfigManager } from "./project_config_manager";
20+
import { DEFAULT_URL_TEMPLATE, DEFAULT_AUTHENTICATED_URL_TEMPLATE } from './constant';
21+
import { RequestHandler } from "../utils/http_request_handler/http";
22+
23+
export type UniversalPollingConfigManagerConfig = PollingConfigManagerConfig & {
24+
requestHandler: RequestHandler;
25+
}
26+
27+
export const createPollingProjectConfigManager = (config: UniversalPollingConfigManagerConfig): OpaqueConfigManager => {
28+
const defaultConfig = {
29+
autoUpdate: true,
30+
};
31+
return getOpaquePollingConfigManager({ ...defaultConfig, ...config });
32+
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"import": "./dist/index.react_native.es.min.js",
4343
"require": "./dist/index.react_native.min.js"
4444
},
45-
"./lite": {
45+
"./universal": {
4646
"types": "./dist/index.lite.d.ts",
4747
"node": "./dist/index.lite.min.js",
4848
"import": "./dist/index.lite.es.js",

rollup.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ const bundles = {
141141
'cjs-node-min': cjsBundleFor('node'),
142142
'cjs-browser-min': cjsBundleFor('browser'),
143143
'cjs-react-native-min': cjsBundleFor('react_native'),
144-
'cjs-lite': cjsBundleFor('lite'),
144+
'cjs-universal': cjsBundleFor('universal'),
145145
'esm-browser-min': esmBundleFor('browser'),
146146
'esm-node-min': esmBundleFor('node', { ext: '.mjs' }),
147147
'esm-react-native-min': esmBundleFor('react_native'),
148-
'esm-lite': esmBundleFor('lite'),
148+
'esm-universal': esmBundleFor('universal'),
149149
'json-schema': jsonSchemaBundle,
150150
umd: umdBundle,
151151
};

0 commit comments

Comments
 (0)