• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-js / 7290294576

21 Dec 2023 03:46PM UTC coverage: 0.0% (-86.5%) from 86.51%
7290294576

Pull #6257

github

kneth
Calculate estimate for PBS. Deprecate old arguments
Pull Request #6257: Progress notification for Flexible Sync

0 of 1275 branches covered (0.0%)

Branch coverage included in aggregate %.

0 of 7 new or added lines in 1 file covered. (0.0%)

2258 existing lines in 60 files now uncovered.

0 of 2582 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/realm/src/ClassMap.ts
1
////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2022 Realm Inc.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
////////////////////////////////////////////////////////////////////////////
18

19
import {
20
  CanonicalObjectSchema,
21
  Constructor,
22
  INTERNAL,
23
  KEY_ARRAY,
24
  KEY_SET,
25
  PropertyMap,
26
  REALM,
27
  Realm,
28
  RealmObject,
29
  RealmObjectConstructor,
30
  assert,
31
  binding,
32
  getClassHelpers,
33
  setClassHelpers,
34
} from "./internal";
35

36
/** @internal */
37
export class ClassMap {
38
  private mapping: Record<string, Constructor<unknown>>;
39
  private nameByTableKey: Record<binding.TableKey, string>;
40

41
  private static createNamedConstructor<T extends Constructor>(name: string): T {
UNCOV
42
    const result = function () {
×
43
      /* no-op */
44
    };
45
    // Need to use `defineProperty` since it isn't writable
UNCOV
46
    Object.defineProperty(result, "name", { value: name });
×
UNCOV
47
    return result as unknown as T;
×
48
  }
49

50
  private static createClass<T extends RealmObjectConstructor = RealmObjectConstructor>(
51
    schema: binding.ObjectSchema,
52
    constructor: Constructor | undefined,
53
  ): T {
UNCOV
54
    const result = ClassMap.createNamedConstructor<T>(schema.name);
×
55
    // Make the new constructor extend RealmObject
56
    // TODO: Use the end-users constructor, instead of `RealmObject` if provided
UNCOV
57
    if (constructor) {
×
UNCOV
58
      Object.setPrototypeOf(result, constructor);
×
UNCOV
59
      Object.setPrototypeOf(result.prototype, constructor.prototype);
×
60
    } else {
UNCOV
61
      Object.setPrototypeOf(result, RealmObject);
×
UNCOV
62
      Object.setPrototypeOf(result.prototype, RealmObject.prototype);
×
63
    }
UNCOV
64
    return result;
×
65
  }
66

67
  private static defineProperties(
68
    constructor: Constructor,
69
    schema: binding.ObjectSchema,
70
    propertyMap: PropertyMap,
71
    realm: Realm,
72
  ) {
73
    // Create bound functions for getting and setting properties
UNCOV
74
    const properties = [...schema.persistedProperties, ...schema.computedProperties];
×
UNCOV
75
    const propertyNames = properties.map((p) => p.publicName || p.name);
×
76

77
    // Set up accessors for the properties declared in the schema
UNCOV
78
    for (const property of properties) {
×
UNCOV
79
      const propertyName = property.publicName || property.name;
×
UNCOV
80
      const { get, set } = propertyMap.get(propertyName);
×
UNCOV
81
      Object.defineProperty(constructor.prototype, propertyName, {
×
82
        enumerable: true,
83
        get(this: RealmObject) {
UNCOV
84
          return get(this[INTERNAL]);
×
85
        },
86
        set(this: RealmObject, value: unknown) {
UNCOV
87
          set(this[INTERNAL], value);
×
88
        },
89
      });
90
    }
91

UNCOV
92
    Object.defineProperty(constructor.prototype, REALM, {
×
93
      enumerable: false,
94
      configurable: false,
95
      writable: false,
96
      value: realm,
97
    });
UNCOV
98
    Object.defineProperty(constructor.prototype, KEY_ARRAY, {
×
99
      enumerable: false,
100
      configurable: false,
101
      writable: false,
102
      value: propertyNames,
103
    });
UNCOV
104
    Object.defineProperty(constructor.prototype, KEY_SET, {
×
105
      enumerable: false,
106
      configurable: false,
107
      writable: false,
108
      value: new Set(propertyNames),
109
    });
110
  }
111

112
  constructor(
113
    realm: Realm,
114
    realmSchema: readonly binding.ObjectSchema[],
115
    canonicalRealmSchema: CanonicalObjectSchema[],
116
  ) {
UNCOV
117
    this.mapping = Object.fromEntries(
×
118
      realmSchema.map((objectSchema, index) => {
UNCOV
119
        const canonicalObjectSchema: CanonicalObjectSchema = canonicalRealmSchema[index];
×
UNCOV
120
        assert.object(canonicalObjectSchema);
×
121
        // Create the wrapping class first
UNCOV
122
        const constructor = ClassMap.createClass(objectSchema, canonicalObjectSchema.ctor);
×
123
        // Create property getters and setters
UNCOV
124
        const properties = new PropertyMap();
×
125
        // Setting the helpers on the class
UNCOV
126
        setClassHelpers(constructor, {
×
127
          constructor,
128
          objectSchema,
129
          canonicalObjectSchema,
130
          properties,
131
          wrapObject(obj) {
UNCOV
132
            if (obj.isValid) {
×
UNCOV
133
              return RealmObject.createWrapper(obj, constructor);
×
134
            } else {
UNCOV
135
              return null;
×
136
            }
137
          },
138
        });
UNCOV
139
        return [objectSchema.name, constructor];
×
140
      }),
141
    );
142

UNCOV
143
    this.nameByTableKey = Object.fromEntries(realmSchema.map(({ name, tableKey }) => [tableKey, name]));
×
144

UNCOV
145
    for (const [index, objectSchema] of realmSchema.entries()) {
×
UNCOV
146
      const canonicalObjectSchema = canonicalRealmSchema[index];
×
UNCOV
147
      const defaults = Object.fromEntries(
×
148
        Object.entries(canonicalObjectSchema.properties).map(([name, property]) => {
UNCOV
149
          return [name, property.default];
×
150
        }),
151
      );
UNCOV
152
      const constructor = this.mapping[objectSchema.name];
×
153
      // Get the uninitialized property map
UNCOV
154
      const { properties } = getClassHelpers(constructor as typeof RealmObject);
×
155
      // Initialize the property map, now that all classes have helpers set
UNCOV
156
      properties.initialize(objectSchema, defaults, {
×
157
        realm,
UNCOV
158
        getClassHelpers: (name: string) => this.getHelpers(name),
×
159
      });
160
      // Transfer property getters and setters onto the prototype of the class
UNCOV
161
      ClassMap.defineProperties(constructor, objectSchema, properties, realm);
×
162
    }
163
  }
164

165
  public get<T>(arg: string | binding.TableKey | RealmObject<T> | Constructor<RealmObject<T>>): Constructor<T> {
UNCOV
166
    if (typeof arg === "string") {
×
UNCOV
167
      const constructor = this.mapping[arg];
×
UNCOV
168
      if (!constructor) {
×
UNCOV
169
        throw new Error(`Object type '${arg}' not found in schema.`);
×
170
      }
UNCOV
171
      return constructor as Constructor<T>;
×
UNCOV
172
    } else if (arg instanceof RealmObject) {
×
UNCOV
173
      return this.get(arg.constructor.name) as Constructor<T>;
×
UNCOV
174
    } else if (typeof arg === "function") {
×
UNCOV
175
      assert.extends(arg, RealmObject);
×
UNCOV
176
      assert.object(arg.schema, "schema static");
×
UNCOV
177
      assert.string(arg.schema.name, "name");
×
UNCOV
178
      const result = this.get(arg.schema.name);
×
UNCOV
179
      assert(
×
180
        result === arg || Object.getPrototypeOf(result) === arg,
×
181
        "Constructor was not registered in the schema for this Realm",
182
      );
UNCOV
183
      return result as Constructor<T>;
×
UNCOV
184
    } else if (arg in this.nameByTableKey) {
×
UNCOV
185
      const name = this.nameByTableKey[arg];
×
UNCOV
186
      return this.get(name);
×
187
    } else {
UNCOV
188
      throw new Error("Expected an object schema name, object instance or class");
×
189
    }
190
  }
191

192
  public getHelpers<T>(arg: string | binding.TableKey | RealmObject<T> | Constructor<RealmObject<T>>) {
UNCOV
193
    const constructor = this.get(arg);
×
UNCOV
194
    return getClassHelpers(constructor as unknown as typeof RealmObject);
×
195
  }
196
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc