@oreefy/event 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Oreefy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # @oreefy/event
2
+
3
+ A lightweight, type-safe event emitter for frontend web applications with built-in cross-tab communication support.
4
+
5
+ `@oreefy/event` is a library built for the Oreefy ecosystem. The package is officially developed, maintained, and fully controlled by Oreefy, ensuring long-term stability, consistency, and compatibility across the ecosystem.
6
+
7
+ > Browser only: This package is designed exclusively for `frontend/browser` environments. It requires the native `BroadcastChannel` API and is not intended for Node.js, server-side, or other non-browser environments.
8
+
9
+ ## Required Capabilities
10
+
11
+ - JavaScript / TypeScript
12
+ - A browser environment with native `BroadcastChannel` support
13
+ - Frontend/client-side application
14
+
15
+ <br>
16
+
17
+ # Basic Usage
18
+
19
+ The following example demonstrates a typical `client-side` usage:
20
+
21
+ ```ts
22
+ import { eventInstance } from "@oreefy/event";
23
+
24
+ const event = eventInstance();
25
+
26
+ function listener(data) {
27
+ console.log("Signed in:", data); // { success: true }
28
+ }
29
+
30
+ // Register a listener
31
+ event.on("signedIn", listener);
32
+
33
+ // Remove the listener (Memory Efficient)
34
+ event.off("signedIn", listener);
35
+
36
+ // Emit an event
37
+ event.emit("signedIn", { success: true });
38
+ ```
39
+
40
+ Events are delivered to listeners in the same tab and automatically broadcast to other open tabs via `BroadcastChannel`.
41
+
42
+ # API Reference
43
+
44
+ Import `eventInstance` and create an event instance:
45
+
46
+ ```ts
47
+ import { eventInstance } from "@oreefy/event";
48
+
49
+ const event = eventInstance();
50
+ event.emit();
51
+ event.on();
52
+ event.off();
53
+ ```
54
+
55
+ All operations are _synchronous_.
56
+
57
+ ## `event.emit()`
58
+
59
+ Emits an event with data payload.
60
+
61
+ ```ts
62
+ import { eventInstance } from "@oreefy/event";
63
+
64
+ interface Theme {
65
+ mode: "light" | "dark" | "system";
66
+ fontSize: string;
67
+ // ...
68
+ }
69
+
70
+ const event = eventInstance();
71
+
72
+ // With type safety
73
+ event.emit<Theme>("theme", {
74
+ mode: "system",
75
+ fontSize: "14px",
76
+ });
77
+
78
+ // Without type safety
79
+ event.emit("theme", {
80
+ mode: "system",
81
+ fontSize: "14px",
82
+ });
83
+ ```
84
+
85
+ The event is immediately delivered to all listeners in the current tab and broadcast to other tabs using `BroadcastChannel`.
86
+
87
+ ## `idb.on()`
88
+
89
+ Registers a _listener_ for a specific event.
90
+
91
+ ```ts
92
+ import { eventInstance } from "@oreefy/event";
93
+
94
+ interface Theme {
95
+ mode: "light" | "dark" | "system";
96
+ fontSize: string;
97
+ // ...
98
+ }
99
+
100
+ function listener(theme: Theme) {
101
+ console.log(theme); // { mode: "system", fontSize: "14px" }
102
+ }
103
+
104
+ const event = eventInstance();
105
+ event.on<Theme>("theme", listener);
106
+ ```
107
+
108
+ Multiple listeners can be registered for the same event.
109
+
110
+ ## `idb.off()`
111
+
112
+ Removes a previously registered _listener_.
113
+
114
+ ```ts
115
+ import { eventInstance } from "@oreefy/event";
116
+
117
+ interface Theme {
118
+ mode: "light" | "dark" | "system";
119
+ fontSize: string;
120
+ // ...
121
+ }
122
+
123
+ function listener(theme: Theme) {
124
+ console.log(theme);
125
+ }
126
+
127
+ const event = eventInstance();
128
+ event.on<Theme>("theme", listener);
129
+ event.off("theme", handler); // Must pass the same function reference
130
+ ```
131
+
132
+ If the listener is not registered, the call is silently ignored.
133
+
134
+ ## Cross-Tab Communication
135
+
136
+ `@oreefy/event` uses the browser’s native `BroadcastChannel` API to share events across tabs.
137
+
138
+ ### Tab A:
139
+
140
+ ```ts
141
+ event.emit("signedIn", true);
142
+ ```
143
+
144
+ ### Tab B:
145
+
146
+ ```ts
147
+ event.on("signedIn", (data) => {
148
+ console.log("Received from another tab:", data);
149
+ });
150
+ ```
151
+
152
+ The originating tab does not receive its own broadcast message, preventing duplicate delivery.
153
+
154
+ ## Same-Tab vs Cross-Tab Behavior
155
+
156
+ When you call `event.emit()`
157
+
158
+ 1. The event is delivered immediately to listeners in the current tab.
159
+ 2. The event is broadcast to other tabs via `BroadcastChannel`.
160
+
161
+ ## Event Listener Errors
162
+
163
+ Errors thrown inside a listener do not prevent other listeners from running.
164
+
165
+ ```ts
166
+ event.on("example", () => {
167
+ throw new Error("Something went wrong");
168
+ });
169
+
170
+ event.on("example", (data) => {
171
+ console.log("This listener still executes:", data);
172
+ });
173
+
174
+ event.emit("example", true);
175
+ ```
176
+
177
+ An error thrown by one listener does not interrupt the event dispatch process.
178
+
179
+ ## Browser Compatibility
180
+
181
+ This package depends on the native `BroadcastChannel` Web API. It is intended for modern browsers that provide `BroadcastChannel` support.
182
+
183
+ It is not designed for:
184
+
185
+ - Node.js
186
+ - Server-side applications
187
+ - Backend services
188
+ - Serverless runtime environments
189
+ - Cloudflare Workers
190
+ - Other non-browser JavaScript runtimes
191
+
192
+ Use this package when the code is running in a browser/client environment.
193
+
194
+ ## About Oreefy
195
+
196
+ [**Oreefy**](https://www.oreefy.com) is an affordable business ecosystem designed for small to enterprise businesses. [**Oreefy**](https://www.oreefy.com) provides essential software you need for your modern business within a single ecosystem. It will save you significant time, effort, and money.
197
+
198
+ ## License
199
+
200
+ MIT © Oreefy
@@ -0,0 +1,16 @@
1
+ type EventListener<T = any> = (data: T) => void;
2
+ declare class Event {
3
+ private static _instance;
4
+ private static readonly TAB_ID;
5
+ private listeners;
6
+ private channel;
7
+ private _triggerLocalListeners;
8
+ private constructor();
9
+ static _initInstance(): Event;
10
+ emit<T = any>(name: string, data: T): void;
11
+ on<T = any>(name: string, listener: EventListener<T>): void;
12
+ off<T = any>(name: string, listener: EventListener<T>): void;
13
+ }
14
+ declare const eventInstance: typeof Event._initInstance;
15
+
16
+ export { eventInstance };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ var r=class s{static _instance;static TAB_ID=crypto.randomUUID();listeners=new Map;channel=new BroadcastChannel("@oreefy/idb");_triggerLocalListeners(t,e){let n=this.listeners.get(t);if(n)for(let i of n)try{i(e);}catch{}}constructor(){this.channel.addEventListener("message",t=>{let{name:e,data:n,sourceTabId:i}=t.data||{};e&&i!==s.TAB_ID&&this._triggerLocalListeners(e,n);});}static _initInstance(){return s._instance||(s._instance=new s),s._instance}emit(t,e){this._triggerLocalListeners(t,e),this.channel.postMessage({name:t,data:e,sourceTabId:s.TAB_ID});}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e);}off(t,e){let n=this.listeners.get(t);n&&(n.delete(e),n.size===0&&this.listeners.delete(t));}},a=r._initInstance;export{a as eventInstance};
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@oreefy/event",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "types": "./dist/index.d.ts",
6
+ "module": "./dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "LICENSE",
16
+ "README.md"
17
+ ],
18
+ "sideEffects": false,
19
+ "scripts": {
20
+ "dev": "tsup --watch",
21
+ "build": "tsup",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "devDependencies": {
25
+ "tsup": "^8.5.1",
26
+ "typescript": "^5.9.3"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/oreefy/oreefy-event.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/oreefy/oreefy-event/issues"
34
+ },
35
+ "homepage": "https://github.com/oreefy/oreefy-event#readme",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "license": "MIT",
40
+ "author": "Oreefy",
41
+ "description": "A lightweight, type-safe event emitter for frontend web applications with built-in cross-tab communication support.",
42
+ "keywords": [
43
+ "event",
44
+ "listener",
45
+ "emitter",
46
+ "broadcastchannel",
47
+ "clinet",
48
+ "browser",
49
+ "ecosystem",
50
+ "oreefy"
51
+ ]
52
+ }