@ad-execute-manager/count-recorder 2.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 singcl
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,272 @@
1
+ # @ad-execute-manager/count-recorder
2
+
3
+ A flexible count recorder utility for JavaScript applications with daily tracking, expiration support, and user-specific counting.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ad-execute-manager/count-recorder
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - **Daily Count Tracking**: Track counts on a daily basis with automatic reset
14
+ - **Expiration Support**: Set expiration times for count data, including 'today' option
15
+ - **User-specific Counting**: Track counts per user with automatic userId integration
16
+ - **Storage Integration**: Uses @ad-execute-manager/storage for persistent storage
17
+ - **Total Count Management**: Set and manage total count limits
18
+ - **Remaining Count Calculation**: Automatically calculate remaining counts
19
+ - **TypeScript Support**: Includes TypeScript type definitions
20
+ - **Error Handling**: Built-in error handling for required parameters
21
+
22
+ ## Usage
23
+
24
+ ### Basic Usage
25
+
26
+ ```javascript
27
+ import { CountRecorder } from '@ad-execute-manager/count-recorder';
28
+
29
+ // Create a count recorder instance
30
+ const dailyTaskRecorder = CountRecorder.new({
31
+ local_sign: 'daily_task_recorder',
32
+ total: 5, // Maximum 5 times per day
33
+ expire: 'today', // Reset daily
34
+ userId: 'user123' // User-specific counting
35
+ });
36
+
37
+ // Check remaining counts
38
+ const remaining = dailyTaskRecorder.remain();
39
+ console.log('Remaining tasks:', remaining);
40
+
41
+ if (remaining > 0) {
42
+ // Perform the task
43
+ console.log('Performing task...');
44
+
45
+ // Update the count
46
+ dailyTaskRecorder.updateToday();
47
+
48
+ console.log('Task performed, count updated');
49
+ } else {
50
+ console.log('Daily limit reached');
51
+ }
52
+ ```
53
+
54
+ ### Advanced Usage
55
+
56
+ ```javascript
57
+ import { CountRecorder } from '@ad-execute-manager/count-recorder';
58
+
59
+ // Create multiple recorders for different purposes
60
+
61
+ // Daily ad impression recorder
62
+ const adRecorder = CountRecorder.new({
63
+ local_sign: 'ad_impression_recorder',
64
+ total: 10, // Maximum 10 ads per day
65
+ expire: 'today',
66
+ userId: 'user123'
67
+ });
68
+
69
+ // Weekly feature usage recorder
70
+ const featureRecorder = CountRecorder.new({
71
+ local_sign: 'feature_usage_recorder',
72
+ total: 20, // Maximum 20 uses per week
73
+ expire: 7 * 24 * 60 * 60 * 1000, // 7 days expiration
74
+ userId: 'user123'
75
+ });
76
+
77
+ // Check and use ad impressions
78
+ function showAd() {
79
+ const remaining = adRecorder.remain();
80
+
81
+ if (remaining > 0) {
82
+ console.log('Showing ad...');
83
+ adRecorder.updateToday();
84
+ console.log('Ad shown, remaining:', adRecorder.remain());
85
+ return true;
86
+ } else {
87
+ console.log('Ad limit reached for today');
88
+ return false;
89
+ }
90
+ }
91
+
92
+ // Check and use feature
93
+ function usePremiumFeature() {
94
+ const remaining = featureRecorder.remain();
95
+
96
+ if (remaining > 0) {
97
+ console.log('Using premium feature...');
98
+ featureRecorder.updateToday();
99
+ console.log('Feature used, remaining:', featureRecorder.remain());
100
+ return true;
101
+ } else {
102
+ console.log('Feature usage limit reached');
103
+ return false;
104
+ }
105
+ }
106
+
107
+ // Usage examples
108
+ // showAd();
109
+ // usePremiumFeature();
110
+ ```
111
+
112
+ ## API
113
+
114
+ ### Constructor
115
+
116
+ ```javascript
117
+ new CountRecorder(args)
118
+ ```
119
+
120
+ - **args** (Object): Configuration arguments
121
+ - **local_sign** (String): Local storage identifier (required)
122
+ - **total** (Number): Total count limit, defaults to 0
123
+ - **expire** (Number|'today'): Expiration time in milliseconds or 'today' for day-bound, defaults to 'today'
124
+ - **userId** (String|Number): User ID for user-specific counting
125
+
126
+ ### Methods
127
+
128
+ - **remain()**: Get remaining count
129
+ - **returns** (Number): Remaining count
130
+
131
+ - **updateToday()**: Update today's count
132
+
133
+ ### Static Methods
134
+
135
+ - **CountRecorder.new(args)**: Create a new CountRecorder instance
136
+ - **args** (Object): Same as constructor arguments
137
+ - **returns** (CountRecorder): New CountRecorder instance
138
+
139
+ ## Examples
140
+
141
+ ### Example 1: Daily Login Tracker
142
+
143
+ ```javascript
144
+ import { CountRecorder } from '@ad-execute-manager/count-recorder';
145
+
146
+ // Create login recorder
147
+ const loginRecorder = CountRecorder.new({
148
+ local_sign: 'daily_login_recorder',
149
+ total: 1, // Only one login count per day
150
+ expire: 'today',
151
+ userId: 'user123'
152
+ });
153
+
154
+ // Check if user has already logged in today
155
+ function checkDailyLogin() {
156
+ const remaining = loginRecorder.remain();
157
+
158
+ if (remaining > 0) {
159
+ console.log('First login today');
160
+ // Give daily login bonus
161
+ giveDailyBonus();
162
+ // Update login count
163
+ loginRecorder.updateToday();
164
+ } else {
165
+ console.log('Already logged in today');
166
+ }
167
+ }
168
+
169
+ // Give daily bonus
170
+ function giveDailyBonus() {
171
+ console.log('Giving daily login bonus...');
172
+ // Bonus logic here
173
+ }
174
+
175
+ // Usage
176
+ // checkDailyLogin();
177
+ ```
178
+
179
+ ### Example 2: Ad Impression Limiter
180
+
181
+ ```javascript
182
+ import { CountRecorder } from '@ad-execute-manager/count-recorder';
183
+
184
+ // Create ad impression recorder
185
+ const adRecorder = CountRecorder.new({
186
+ local_sign: 'ad_impression_recorder',
187
+ total: 8, // Maximum 8 ads per day
188
+ expire: 'today',
189
+ userId: 'user123'
190
+ });
191
+
192
+ // Check if ad can be shown
193
+ function canShowAd() {
194
+ const remaining = adRecorder.remain();
195
+ return remaining > 0;
196
+ }
197
+
198
+ // Show ad and update count
199
+ function showAd() {
200
+ if (canShowAd()) {
201
+ console.log('Showing ad...');
202
+ // Ad showing logic here
203
+ adRecorder.updateToday();
204
+ console.log('Ad shown, remaining impressions:', adRecorder.remain());
205
+ return true;
206
+ } else {
207
+ console.log('Ad limit reached for today');
208
+ return false;
209
+ }
210
+ }
211
+
212
+ // Check remaining ad impressions
213
+ function checkAdLimit() {
214
+ const remaining = adRecorder.remain();
215
+ console.log(`Remaining ad impressions: ${remaining}/8`);
216
+ return remaining;
217
+ }
218
+
219
+ // Usage examples
220
+ // checkAdLimit();
221
+ // showAd();
222
+ ```
223
+
224
+ ### Example 3: Feature Usage Tracker
225
+
226
+ ```javascript
227
+ import { CountRecorder } from '@ad-execute-manager/count-recorder';
228
+
229
+ // Create feature usage recorder
230
+ const featureRecorder = CountRecorder.new({
231
+ local_sign: 'premium_feature_recorder',
232
+ total: 15, // Maximum 15 uses per day
233
+ expire: 'today',
234
+ userId: 'user123'
235
+ });
236
+
237
+ // Use premium feature
238
+ function usePremiumFeature(featureName) {
239
+ const remaining = featureRecorder.remain();
240
+
241
+ if (remaining > 0) {
242
+ console.log(`Using premium feature: ${featureName}`);
243
+ // Feature usage logic here
244
+ featureRecorder.updateToday();
245
+ console.log(`Feature used, remaining uses: ${featureRecorder.remain()}/15`);
246
+ return true;
247
+ } else {
248
+ console.log('Premium feature usage limit reached for today');
249
+ return false;
250
+ }
251
+ }
252
+
253
+ // Check feature usage status
254
+ function checkFeatureUsage() {
255
+ const remaining = featureRecorder.remain();
256
+ const used = 15 - remaining;
257
+ console.log(`Premium feature usage: ${used}/15 today`);
258
+ return { used, remaining, total: 15 };
259
+ }
260
+
261
+ // Usage examples
262
+ // checkFeatureUsage();
263
+ // usePremiumFeature('AI Summarizer');
264
+ ```
265
+
266
+ ## Dependencies
267
+
268
+ - **@ad-execute-manager/storage**: For persistent storage of count data
269
+
270
+ ## License
271
+
272
+ MIT
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @typedef {object} IConstructorArgs
3
+ * @property {string} [sign] 初始化标识
4
+ * @property {string} local_sign 本地存储标识
5
+ * @property {number} [total] 总次数
6
+ * @property {number|'today'} [expire] 过期时间(毫秒)或'today'表示当天有效,可选
7
+ * @property {string | number} [userId] 用户ID
8
+ *
9
+ */
10
+ export class CountRecorder {
11
+ /**
12
+ *
13
+ * @param {IConstructorArgs} args
14
+ * @returns {CountRecorder}
15
+ */
16
+ static "new"(args: IConstructorArgs): CountRecorder;
17
+ /**
18
+ *
19
+ * @param {IConstructorArgs} args
20
+ */
21
+ constructor(args: IConstructorArgs);
22
+ _total: number;
23
+ _local_sign: string;
24
+ _expire: string;
25
+ storage: Storage;
26
+ _init(): void;
27
+ /**
28
+ * 获取次数
29
+ * @returns {number} 次数
30
+ */
31
+ _adTimes(): number;
32
+ _safeLocalValue(v: any): any;
33
+ _initLocalTimes(): void;
34
+ updateToday(): void;
35
+ remain(): number;
36
+ }
37
+ export type IConstructorArgs = {
38
+ /**
39
+ * 初始化标识
40
+ */
41
+ sign?: string;
42
+ /**
43
+ * 本地存储标识
44
+ */
45
+ local_sign: string;
46
+ /**
47
+ * 总次数
48
+ */
49
+ total?: number;
50
+ /**
51
+ * 过期时间(毫秒)或'today'表示当天有效,可选
52
+ */
53
+ expire?: number | "today";
54
+ /**
55
+ * 用户ID
56
+ */
57
+ userId?: string | number;
58
+ };
59
+ import { Storage } from '@ad-execute-manager/storage';
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var _ in t)__webpack_require__.o(t,_)&&!__webpack_require__.o(e,_)&&Object.defineProperty(e,_,{enumerable:!0,get:t[_]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{CountRecorder:()=>CountRecorder});const storage_namespaceObject=require("@ad-execute-manager/storage");class CountRecorder{_total=0;_local_sign="";_expire="today";constructor(e){if(this.storage=storage_namespaceObject.Storage.new({userId:e.userId}),!e.local_sign)throw Error("local_sign is required");this._local_sign=e.local_sign,this._total=e.total??0,this._expire=e.expire??"today",this._init()}_init(){this._initLocalTimes()}_adTimes(){return this._total}_safeLocalValue(e){return"object"!=typeof e||null===e?{}:e}_initLocalTimes(){let e=this._adTimes(),t=this.storage.getUserItem(this._local_sign),_=this._safeLocalValue(t);_&&(null==_?void 0:_.total)==e||this.storage.setUserItem(this._local_sign,{total:e,today:(null==_?void 0:_.today)??0},this._expire)}updateToday(){let e=this._adTimes(),t=this.storage.getUserItem(this._local_sign),_=this._safeLocalValue(t),r=(null==_?void 0:_.today)??0;this.storage.setUserItem(this._local_sign,{total:e,today:r+1},this._expire)}remain(){let e=this.storage.getUserItem(this._local_sign),t=this._safeLocalValue(e),_=(null==t?void 0:t.today)??0;return Number((null==t?void 0:t.total)??0)-Number(_)}static new(e){return new CountRecorder(e)}}for(var __rspack_i in exports.CountRecorder=__webpack_exports__.CountRecorder,__webpack_exports__)-1===["CountRecorder"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1 @@
1
+ export { CountRecorder } from "./CountRecorder.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{Storage as t}from"@ad-execute-manager/storage";class e{_total=0;_local_sign="";_expire="today";constructor(e){if(this.storage=t.new({userId:e.userId}),!e.local_sign)throw Error("local_sign is required");this._local_sign=e.local_sign,this._total=e.total??0,this._expire=e.expire??"today",this._init()}_init(){this._initLocalTimes()}_adTimes(){return this._total}_safeLocalValue(t){return"object"!=typeof t||null===t?{}:t}_initLocalTimes(){let t=this._adTimes(),e=this.storage.getUserItem(this._local_sign),s=this._safeLocalValue(e);s&&(null==s?void 0:s.total)==t||this.storage.setUserItem(this._local_sign,{total:t,today:(null==s?void 0:s.today)??0},this._expire)}updateToday(){let t=this._adTimes(),e=this.storage.getUserItem(this._local_sign),s=this._safeLocalValue(e),i=(null==s?void 0:s.today)??0;this.storage.setUserItem(this._local_sign,{total:t,today:i+1},this._expire)}remain(){let t=this.storage.getUserItem(this._local_sign),e=this._safeLocalValue(t),s=(null==e?void 0:e.today)??0;return Number((null==e?void 0:e.total)??0)-Number(s)}static new(t){return new e(t)}}export{e as CountRecorder};
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@ad-execute-manager/count-recorder",
3
+ "version": "2.0.1",
4
+ "description": "A flexible count recorder utility for JavaScript applications with multiple count recorder adapters and customizable options.",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./dist/index.js",
9
+ "require": "./dist/index.cjs",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "main": "./dist/index.cjs",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "author": {
19
+ "name": "singcl",
20
+ "email": "iambabyer@gmail.com",
21
+ "url": "https://github.com/singcl"
22
+ },
23
+ "license": "MIT",
24
+ "homepage": "https://npmjs.com/package/@ad-execute-manager/logger",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/singcl/ad-execute-manager.git",
28
+ "directory": "packages/logger"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/singcl/ad-execute-manager/issues"
32
+ },
33
+ "engines": {
34
+ "node": ">=14.0.0"
35
+ },
36
+ "keywords": [
37
+ "logger",
38
+ "logging",
39
+ "utility",
40
+ "javascript",
41
+ "nodejs",
42
+ "typescript",
43
+ "log-levels",
44
+ "debug"
45
+ ],
46
+ "scripts": {
47
+ "build": "rslib build && tsc",
48
+ "dev": "rslib build --watch",
49
+ "format": "prettier --write .",
50
+ "lint": "eslint .",
51
+ "test": "rstest",
52
+ "prepublishOnly": "npm run build"
53
+ },
54
+ "peerDependencies": {
55
+ "@ad-execute-manager/storage": "^2.0.1"
56
+ },
57
+ "devDependencies": {
58
+ "@babel/eslint-parser": "^7.28.5",
59
+ "@babel/preset-env": "^7.28.5",
60
+ "@eslint/js": "^9.39.1",
61
+ "@rslib/core": "^0.18.5",
62
+ "@rstest/core": "^0.7.2",
63
+ "eslint": "^9.39.2",
64
+ "eslint-plugin-import": "^2.32.0",
65
+ "globals": "^16.5.0",
66
+ "prettier": "^3.7.3",
67
+ "typescript": "^5.9.3"
68
+ }
69
+ }