js-bao 0.5.1 → 0.5.2
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/README.md +124 -30
- package/dist/browser.cjs +586 -265
- package/dist/browser.d.cts +21 -0
- package/dist/browser.d.ts +21 -0
- package/dist/browser.js +588 -263
- package/dist/client.cjs +42 -6
- package/dist/client.d.cts +71 -0
- package/dist/client.d.ts +71 -0
- package/dist/client.js +39 -4
- package/dist/cloudflare-do.cjs +462 -215
- package/dist/cloudflare-do.d.cts +111 -1
- package/dist/cloudflare-do.d.ts +111 -1
- package/dist/cloudflare-do.js +459 -213
- package/dist/cloudflare.cjs +270 -23
- package/dist/cloudflare.d.cts +276 -1
- package/dist/cloudflare.d.ts +276 -1
- package/dist/cloudflare.js +267 -21
- package/dist/codegen-v2.cjs +77 -19
- package/dist/codegen.cjs +2 -1
- package/dist/index.cjs +551 -224
- package/dist/index.d.cts +57 -1
- package/dist/index.d.ts +57 -1
- package/dist/index.js +549 -221
- package/dist/node.cjs +775 -291
- package/dist/node.d.cts +179 -1
- package/dist/node.d.ts +179 -1
- package/dist/node.js +762 -288
- package/package.json +2 -1
package/dist/client.cjs
CHANGED
|
@@ -93,37 +93,73 @@ var init_yjsValues = __esm({
|
|
|
93
93
|
}
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
+
// src/models/writeLifecycle.ts
|
|
97
|
+
function registerFunctionDefaultGenerator(name, fn) {
|
|
98
|
+
FUNCTION_DEFAULT_GENERATORS.set(name, fn);
|
|
99
|
+
}
|
|
100
|
+
var Y2, import_ulid, KNOWN_FIELD_TYPE_MAP, KNOWN_FIELD_TYPES, FUNCTION_DEFAULT_GENERATORS;
|
|
101
|
+
var init_writeLifecycle = __esm({
|
|
102
|
+
"src/models/writeLifecycle.ts"() {
|
|
103
|
+
"use strict";
|
|
104
|
+
Y2 = __toESM(require("yjs"), 1);
|
|
105
|
+
import_ulid = require("ulid");
|
|
106
|
+
KNOWN_FIELD_TYPE_MAP = {
|
|
107
|
+
string: true,
|
|
108
|
+
number: true,
|
|
109
|
+
boolean: true,
|
|
110
|
+
date: true,
|
|
111
|
+
id: true,
|
|
112
|
+
stringset: true
|
|
113
|
+
};
|
|
114
|
+
KNOWN_FIELD_TYPES = new Set(Object.keys(KNOWN_FIELD_TYPE_MAP));
|
|
115
|
+
FUNCTION_DEFAULT_GENERATORS = /* @__PURE__ */ new Map();
|
|
116
|
+
registerFunctionDefaultGenerator("generate_ulid", () => (0, import_ulid.ulid)());
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
96
120
|
// src/models/metaSync.ts
|
|
97
121
|
function registerFunctionDefault(fn, name) {
|
|
98
122
|
KNOWN_FUNCTION_DEFAULTS.set(fn, name);
|
|
99
123
|
}
|
|
100
|
-
var
|
|
124
|
+
var Y3, KNOWN_FUNCTION_DEFAULTS;
|
|
101
125
|
var init_metaSync = __esm({
|
|
102
126
|
"src/models/metaSync.ts"() {
|
|
103
127
|
"use strict";
|
|
104
|
-
|
|
128
|
+
Y3 = __toESM(require("yjs"), 1);
|
|
105
129
|
init_yjsValues();
|
|
130
|
+
init_writeLifecycle();
|
|
106
131
|
KNOWN_FUNCTION_DEFAULTS = /* @__PURE__ */ new WeakMap();
|
|
107
132
|
}
|
|
108
133
|
});
|
|
109
134
|
|
|
135
|
+
// src/utils/uniqueIndex.ts
|
|
136
|
+
var Y4;
|
|
137
|
+
var init_uniqueIndex = __esm({
|
|
138
|
+
"src/utils/uniqueIndex.ts"() {
|
|
139
|
+
"use strict";
|
|
140
|
+
Y4 = __toESM(require("yjs"), 1);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
110
144
|
// src/models/BaseModel.ts
|
|
111
145
|
function generateULID() {
|
|
112
|
-
return (0,
|
|
146
|
+
return (0, import_ulid2.ulid)();
|
|
113
147
|
}
|
|
114
|
-
var
|
|
148
|
+
var Y5, import_ulid2, Logger;
|
|
115
149
|
var init_BaseModel = __esm({
|
|
116
150
|
"src/models/BaseModel.ts"() {
|
|
117
151
|
"use strict";
|
|
118
|
-
|
|
119
|
-
|
|
152
|
+
Y5 = __toESM(require("yjs"), 1);
|
|
153
|
+
import_ulid2 = require("ulid");
|
|
120
154
|
init_StringSet();
|
|
121
155
|
init_documentTypes();
|
|
122
156
|
init_DocumentQueryTranslator();
|
|
123
157
|
init_CursorManager();
|
|
124
158
|
init_sql();
|
|
125
159
|
init_metaSync();
|
|
160
|
+
init_writeLifecycle();
|
|
126
161
|
init_yjsValues();
|
|
162
|
+
init_uniqueIndex();
|
|
127
163
|
Logger = class {
|
|
128
164
|
static _logLevel = 1 /* ERROR */;
|
|
129
165
|
static _logCallback = null;
|
package/dist/client.d.cts
CHANGED
|
@@ -563,6 +563,27 @@ declare class BaseModel implements StringSetChangeTracker {
|
|
|
563
563
|
*/
|
|
564
564
|
static count(this: new (...args: any[]) => any, filter?: DocumentFilter, options?: Pick<QueryOptions, "documents">): Promise<number>;
|
|
565
565
|
static findAll<T extends BaseModel>(this: new (...args: any[]) => T): Promise<T[]>;
|
|
566
|
+
/**
|
|
567
|
+
* Resolve a record by its unique-constraint field values via an engine query.
|
|
568
|
+
* Used as a fallback when the `_uniqueIdx_<model>_<constraint>` map has no
|
|
569
|
+
* entry for a key.
|
|
570
|
+
*
|
|
571
|
+
* The index map is a cache over the SQLite projection, not the source of
|
|
572
|
+
* truth: every record is loaded into the projection on `initializeForDocument`
|
|
573
|
+
* regardless of index presence, but a record written by a client predating
|
|
574
|
+
* index maintenance (legacy data) is missing from the index. Such a record
|
|
575
|
+
* silently escapes both `upsertByUnique` lookups and the `save()` uniqueness
|
|
576
|
+
* check. A query over the constraint fields finds it reliably.
|
|
577
|
+
*
|
|
578
|
+
* Contract: RESOLVE ONLY. Returns the owning record (with `_metaDocId` set to
|
|
579
|
+
* the document that holds it, via `queryOne`) or `null`. Callers decide
|
|
580
|
+
* whether to heal the missing index entry (write paths) and do their own
|
|
581
|
+
* logging — this method never mutates the index, so read paths stay
|
|
582
|
+
* read-only. Mirrors `buildUniqueKey`: a null/undefined value in any
|
|
583
|
+
* constraint field means the record does not participate in the constraint,
|
|
584
|
+
* so no query runs.
|
|
585
|
+
*/
|
|
586
|
+
private static _resolveByUniqueFallback;
|
|
566
587
|
static findByUnique<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), constraintName: string, value: any | any[]): Promise<T | null>;
|
|
567
588
|
static upsertByUnique<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), constraintName: string, uniqueLookupValue: any | any[], dataToUpsert: Partial<Omit<InstanceType<new (...args: any[]) => T>, keyof BaseModel | "toJSON">> & {
|
|
568
589
|
id?: string;
|
|
@@ -758,6 +779,20 @@ interface QueryResponse {
|
|
|
758
779
|
interface SaveResponse {
|
|
759
780
|
success: boolean;
|
|
760
781
|
id: string;
|
|
782
|
+
/**
|
|
783
|
+
* Server-applied field values the DO wrote AFTER the caller's submission
|
|
784
|
+
* inputs were assembled, read back from the final post-hook `data`
|
|
785
|
+
* (#1476, consolidating the #1462 `stamps` channel). This is the single
|
|
786
|
+
* "server-applied fields" channel: it carries both the applied `autoStamps`
|
|
787
|
+
* timestamps and any fields a `beforeSave` hook reported via
|
|
788
|
+
* `serverAppliedFieldNames` (e.g. app-level trigger-computed values). Present
|
|
789
|
+
* only when at least one such field ended up with a value. Lets the Worker
|
|
790
|
+
* thread these values into the change-event `data` it broadcasts to
|
|
791
|
+
* subscribers — otherwise a `select`-listed stamped or trigger-computed field
|
|
792
|
+
* never reaches the frame, because the frame is rebuilt from the submission
|
|
793
|
+
* inputs (which predate the DO-side write).
|
|
794
|
+
*/
|
|
795
|
+
appliedFields?: Record<string, any>;
|
|
761
796
|
}
|
|
762
797
|
interface DeleteResponse {
|
|
763
798
|
success: boolean;
|
|
@@ -814,6 +849,8 @@ interface PatchRequest {
|
|
|
814
849
|
interface PatchResponse {
|
|
815
850
|
success: boolean;
|
|
816
851
|
id: string;
|
|
852
|
+
/** Server-applied field values (#1476). See `SaveResponse.appliedFields`. */
|
|
853
|
+
appliedFields?: Record<string, any>;
|
|
817
854
|
}
|
|
818
855
|
interface BatchOperation {
|
|
819
856
|
op: "save" | "patch" | "delete" | "increment" | "addToSet" | "removeFromSet";
|
|
@@ -841,12 +878,46 @@ interface BatchOperation {
|
|
|
841
878
|
}
|
|
842
879
|
interface BatchRequest {
|
|
843
880
|
operations: BatchOperation[];
|
|
881
|
+
/**
|
|
882
|
+
* All-or-nothing execution (#1478). When `true`, the FIRST operation that
|
|
883
|
+
* fails inside the transaction — hook denial, condition / `ifNotExists` /
|
|
884
|
+
* unique violation, record-not-found, or upsert validation error — aborts
|
|
885
|
+
* the whole batch: every write is rolled back and the handler returns an
|
|
886
|
+
* error naming the failed step with its natural HTTP status (see
|
|
887
|
+
* `BatchOperationResult.status`). When `false` or absent (the default), each
|
|
888
|
+
* operation's outcome is recorded independently and successful siblings
|
|
889
|
+
* commit — the partial-success behavior import-bulk and applyToQuery rely on.
|
|
890
|
+
*/
|
|
891
|
+
atomic?: boolean;
|
|
844
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* Stable, machine-readable failure tag on a failed `BatchOperationResult`
|
|
895
|
+
* (#1478). Derived at each failure site — never inferred from the `error`
|
|
896
|
+
* string. `#1389` (conditional writes + fencing-token enforcement) surfaces its
|
|
897
|
+
* condition / stale-token rejections through this same channel.
|
|
898
|
+
*/
|
|
899
|
+
type BatchFailureCode = "NOT_FOUND" | "HOOK_DENIED" | "CONDITION_NOT_MET" | "ALREADY_EXISTS" | "UNIQUE_VIOLATION" | "VALIDATION_ERROR";
|
|
845
900
|
interface BatchOperationResult {
|
|
846
901
|
success: boolean;
|
|
847
902
|
id: string;
|
|
848
903
|
error?: string;
|
|
904
|
+
/**
|
|
905
|
+
* Structured failure metadata (#1478), present only on a failed result. Both
|
|
906
|
+
* are derived at the failure site, not parsed back out of `error`:
|
|
907
|
+
* - `status` — the natural HTTP status for the cause (404 not found,
|
|
908
|
+
* 403 hook denial, 409 condition / `ifNotExists` / unique conflict,
|
|
909
|
+
* 400 upsert validation).
|
|
910
|
+
* - `code` — a stable machine-readable tag (see `BatchFailureCode`).
|
|
911
|
+
*
|
|
912
|
+
* In atomic mode the handler reads the first failure's `status`/`code` to
|
|
913
|
+
* build the error response, so an increment-on-missing op keeps its 404 and a
|
|
914
|
+
* hook denial keeps its 403 instead of collapsing to a uniform 409.
|
|
915
|
+
*/
|
|
916
|
+
status?: number;
|
|
917
|
+
code?: BatchFailureCode;
|
|
849
918
|
values?: Record<string, number>;
|
|
919
|
+
/** Server-applied field values (#1476). See `SaveResponse.appliedFields`. */
|
|
920
|
+
appliedFields?: Record<string, any>;
|
|
850
921
|
}
|
|
851
922
|
interface BatchResponse {
|
|
852
923
|
results: BatchOperationResult[];
|
package/dist/client.d.ts
CHANGED
|
@@ -563,6 +563,27 @@ declare class BaseModel implements StringSetChangeTracker {
|
|
|
563
563
|
*/
|
|
564
564
|
static count(this: new (...args: any[]) => any, filter?: DocumentFilter, options?: Pick<QueryOptions, "documents">): Promise<number>;
|
|
565
565
|
static findAll<T extends BaseModel>(this: new (...args: any[]) => T): Promise<T[]>;
|
|
566
|
+
/**
|
|
567
|
+
* Resolve a record by its unique-constraint field values via an engine query.
|
|
568
|
+
* Used as a fallback when the `_uniqueIdx_<model>_<constraint>` map has no
|
|
569
|
+
* entry for a key.
|
|
570
|
+
*
|
|
571
|
+
* The index map is a cache over the SQLite projection, not the source of
|
|
572
|
+
* truth: every record is loaded into the projection on `initializeForDocument`
|
|
573
|
+
* regardless of index presence, but a record written by a client predating
|
|
574
|
+
* index maintenance (legacy data) is missing from the index. Such a record
|
|
575
|
+
* silently escapes both `upsertByUnique` lookups and the `save()` uniqueness
|
|
576
|
+
* check. A query over the constraint fields finds it reliably.
|
|
577
|
+
*
|
|
578
|
+
* Contract: RESOLVE ONLY. Returns the owning record (with `_metaDocId` set to
|
|
579
|
+
* the document that holds it, via `queryOne`) or `null`. Callers decide
|
|
580
|
+
* whether to heal the missing index entry (write paths) and do their own
|
|
581
|
+
* logging — this method never mutates the index, so read paths stay
|
|
582
|
+
* read-only. Mirrors `buildUniqueKey`: a null/undefined value in any
|
|
583
|
+
* constraint field means the record does not participate in the constraint,
|
|
584
|
+
* so no query runs.
|
|
585
|
+
*/
|
|
586
|
+
private static _resolveByUniqueFallback;
|
|
566
587
|
static findByUnique<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), constraintName: string, value: any | any[]): Promise<T | null>;
|
|
567
588
|
static upsertByUnique<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), constraintName: string, uniqueLookupValue: any | any[], dataToUpsert: Partial<Omit<InstanceType<new (...args: any[]) => T>, keyof BaseModel | "toJSON">> & {
|
|
568
589
|
id?: string;
|
|
@@ -758,6 +779,20 @@ interface QueryResponse {
|
|
|
758
779
|
interface SaveResponse {
|
|
759
780
|
success: boolean;
|
|
760
781
|
id: string;
|
|
782
|
+
/**
|
|
783
|
+
* Server-applied field values the DO wrote AFTER the caller's submission
|
|
784
|
+
* inputs were assembled, read back from the final post-hook `data`
|
|
785
|
+
* (#1476, consolidating the #1462 `stamps` channel). This is the single
|
|
786
|
+
* "server-applied fields" channel: it carries both the applied `autoStamps`
|
|
787
|
+
* timestamps and any fields a `beforeSave` hook reported via
|
|
788
|
+
* `serverAppliedFieldNames` (e.g. app-level trigger-computed values). Present
|
|
789
|
+
* only when at least one such field ended up with a value. Lets the Worker
|
|
790
|
+
* thread these values into the change-event `data` it broadcasts to
|
|
791
|
+
* subscribers — otherwise a `select`-listed stamped or trigger-computed field
|
|
792
|
+
* never reaches the frame, because the frame is rebuilt from the submission
|
|
793
|
+
* inputs (which predate the DO-side write).
|
|
794
|
+
*/
|
|
795
|
+
appliedFields?: Record<string, any>;
|
|
761
796
|
}
|
|
762
797
|
interface DeleteResponse {
|
|
763
798
|
success: boolean;
|
|
@@ -814,6 +849,8 @@ interface PatchRequest {
|
|
|
814
849
|
interface PatchResponse {
|
|
815
850
|
success: boolean;
|
|
816
851
|
id: string;
|
|
852
|
+
/** Server-applied field values (#1476). See `SaveResponse.appliedFields`. */
|
|
853
|
+
appliedFields?: Record<string, any>;
|
|
817
854
|
}
|
|
818
855
|
interface BatchOperation {
|
|
819
856
|
op: "save" | "patch" | "delete" | "increment" | "addToSet" | "removeFromSet";
|
|
@@ -841,12 +878,46 @@ interface BatchOperation {
|
|
|
841
878
|
}
|
|
842
879
|
interface BatchRequest {
|
|
843
880
|
operations: BatchOperation[];
|
|
881
|
+
/**
|
|
882
|
+
* All-or-nothing execution (#1478). When `true`, the FIRST operation that
|
|
883
|
+
* fails inside the transaction — hook denial, condition / `ifNotExists` /
|
|
884
|
+
* unique violation, record-not-found, or upsert validation error — aborts
|
|
885
|
+
* the whole batch: every write is rolled back and the handler returns an
|
|
886
|
+
* error naming the failed step with its natural HTTP status (see
|
|
887
|
+
* `BatchOperationResult.status`). When `false` or absent (the default), each
|
|
888
|
+
* operation's outcome is recorded independently and successful siblings
|
|
889
|
+
* commit — the partial-success behavior import-bulk and applyToQuery rely on.
|
|
890
|
+
*/
|
|
891
|
+
atomic?: boolean;
|
|
844
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* Stable, machine-readable failure tag on a failed `BatchOperationResult`
|
|
895
|
+
* (#1478). Derived at each failure site — never inferred from the `error`
|
|
896
|
+
* string. `#1389` (conditional writes + fencing-token enforcement) surfaces its
|
|
897
|
+
* condition / stale-token rejections through this same channel.
|
|
898
|
+
*/
|
|
899
|
+
type BatchFailureCode = "NOT_FOUND" | "HOOK_DENIED" | "CONDITION_NOT_MET" | "ALREADY_EXISTS" | "UNIQUE_VIOLATION" | "VALIDATION_ERROR";
|
|
845
900
|
interface BatchOperationResult {
|
|
846
901
|
success: boolean;
|
|
847
902
|
id: string;
|
|
848
903
|
error?: string;
|
|
904
|
+
/**
|
|
905
|
+
* Structured failure metadata (#1478), present only on a failed result. Both
|
|
906
|
+
* are derived at the failure site, not parsed back out of `error`:
|
|
907
|
+
* - `status` — the natural HTTP status for the cause (404 not found,
|
|
908
|
+
* 403 hook denial, 409 condition / `ifNotExists` / unique conflict,
|
|
909
|
+
* 400 upsert validation).
|
|
910
|
+
* - `code` — a stable machine-readable tag (see `BatchFailureCode`).
|
|
911
|
+
*
|
|
912
|
+
* In atomic mode the handler reads the first failure's `status`/`code` to
|
|
913
|
+
* build the error response, so an increment-on-missing op keeps its 404 and a
|
|
914
|
+
* hook denial keeps its 403 instead of collapsing to a uniform 409.
|
|
915
|
+
*/
|
|
916
|
+
status?: number;
|
|
917
|
+
code?: BatchFailureCode;
|
|
849
918
|
values?: Record<string, number>;
|
|
919
|
+
/** Server-applied field values (#1476). See `SaveResponse.appliedFields`. */
|
|
920
|
+
appliedFields?: Record<string, any>;
|
|
850
921
|
}
|
|
851
922
|
interface BatchResponse {
|
|
852
923
|
results: BatchOperationResult[];
|
package/dist/client.js
CHANGED
|
@@ -65,8 +65,32 @@ var init_yjsValues = __esm({
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
// src/models/
|
|
68
|
+
// src/models/writeLifecycle.ts
|
|
69
69
|
import * as Y2 from "yjs";
|
|
70
|
+
import { ulid } from "ulid";
|
|
71
|
+
function registerFunctionDefaultGenerator(name, fn) {
|
|
72
|
+
FUNCTION_DEFAULT_GENERATORS.set(name, fn);
|
|
73
|
+
}
|
|
74
|
+
var KNOWN_FIELD_TYPE_MAP, KNOWN_FIELD_TYPES, FUNCTION_DEFAULT_GENERATORS;
|
|
75
|
+
var init_writeLifecycle = __esm({
|
|
76
|
+
"src/models/writeLifecycle.ts"() {
|
|
77
|
+
"use strict";
|
|
78
|
+
KNOWN_FIELD_TYPE_MAP = {
|
|
79
|
+
string: true,
|
|
80
|
+
number: true,
|
|
81
|
+
boolean: true,
|
|
82
|
+
date: true,
|
|
83
|
+
id: true,
|
|
84
|
+
stringset: true
|
|
85
|
+
};
|
|
86
|
+
KNOWN_FIELD_TYPES = new Set(Object.keys(KNOWN_FIELD_TYPE_MAP));
|
|
87
|
+
FUNCTION_DEFAULT_GENERATORS = /* @__PURE__ */ new Map();
|
|
88
|
+
registerFunctionDefaultGenerator("generate_ulid", () => ulid());
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// src/models/metaSync.ts
|
|
93
|
+
import * as Y3 from "yjs";
|
|
70
94
|
function registerFunctionDefault(fn, name) {
|
|
71
95
|
KNOWN_FUNCTION_DEFAULTS.set(fn, name);
|
|
72
96
|
}
|
|
@@ -75,15 +99,24 @@ var init_metaSync = __esm({
|
|
|
75
99
|
"src/models/metaSync.ts"() {
|
|
76
100
|
"use strict";
|
|
77
101
|
init_yjsValues();
|
|
102
|
+
init_writeLifecycle();
|
|
78
103
|
KNOWN_FUNCTION_DEFAULTS = /* @__PURE__ */ new WeakMap();
|
|
79
104
|
}
|
|
80
105
|
});
|
|
81
106
|
|
|
107
|
+
// src/utils/uniqueIndex.ts
|
|
108
|
+
import * as Y4 from "yjs";
|
|
109
|
+
var init_uniqueIndex = __esm({
|
|
110
|
+
"src/utils/uniqueIndex.ts"() {
|
|
111
|
+
"use strict";
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
82
115
|
// src/models/BaseModel.ts
|
|
83
|
-
import * as
|
|
84
|
-
import { ulid } from "ulid";
|
|
116
|
+
import * as Y5 from "yjs";
|
|
117
|
+
import { ulid as ulid2 } from "ulid";
|
|
85
118
|
function generateULID() {
|
|
86
|
-
return
|
|
119
|
+
return ulid2();
|
|
87
120
|
}
|
|
88
121
|
var Logger;
|
|
89
122
|
var init_BaseModel = __esm({
|
|
@@ -95,7 +128,9 @@ var init_BaseModel = __esm({
|
|
|
95
128
|
init_CursorManager();
|
|
96
129
|
init_sql();
|
|
97
130
|
init_metaSync();
|
|
131
|
+
init_writeLifecycle();
|
|
98
132
|
init_yjsValues();
|
|
133
|
+
init_uniqueIndex();
|
|
99
134
|
Logger = class {
|
|
100
135
|
static _logLevel = 1 /* ERROR */;
|
|
101
136
|
static _logCallback = null;
|