@acalcutt/maplibre-gl-native-test 5.0.2-pre.7 → 5.2.1-pre.10

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.
@@ -1,7 +1,13 @@
1
- ### [Mapbox GL Native](https://github.com/mapbox/mapbox-gl-native) by Mapbox
1
+ ### [Maplibre Native](https://github.com/maplibre/maplibre-native/)
2
2
 
3
3
  ```
4
- mapbox-gl-native Copyright (c) 2014-2020 Mapbox.
4
+ BSD 2-Clause License
5
+
6
+ Copyright (c) 2021 MapLibre contributors
7
+
8
+ Copyright (c) 2018-2021 MapTiler.com
9
+
10
+ Copyright (c) 2014-2020 Mapbox
5
11
 
6
12
  Redistribution and use in source and binary forms, with or without
7
13
  modification, are permitted provided that the following conditions are
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  [![MapLibre Logo](https://maplibre.org/img/maplibre-logo-big.svg)](https://maplibre.org/)
2
2
 
3
- # MapLibre GL Native
3
+ # MapLibre Native
4
4
 
5
- MapLibre GL Native is a free and open-source library for publishing maps in your apps and desktop applications on various platforms. Fast displaying of maps is possible thanks to GPU-accelerated vector tile rendering.
5
+ [![codecov](https://codecov.io/github/maplibre/maplibre-native/branch/main/graph/badge.svg?token=8ZQRRY56ZA)](https://codecov.io/github/maplibre/maplibre-native) [![](https://img.shields.io/badge/Slack-%23maplibre--native-2EB67D?logo=slack)](https://slack.openstreetmap.us/)
6
+
7
+ MapLibre Native is a free and open-source library for publishing maps in your apps and desktop applications on various platforms. Fast displaying of maps is possible thanks to GPU-accelerated vector tile rendering.
6
8
 
7
9
  This project originated as a fork of Mapbox GL Native, before their switch to a non-OSS license in December 2020. For more information, see: [`FORK.md`](./FORK.md).
8
10
 
@@ -12,22 +14,22 @@ This project originated as a fork of Mapbox GL Native, before their switch to a
12
14
 
13
15
  ## Getting Started
14
16
 
15
- To get started with MapLibre GL Native, go to your platform below.
17
+ To get started with MapLibre Native, go to your platform below.
16
18
 
17
19
  ## Documentation
18
20
 
19
- The documentation of MapLibre GL Native is a work in progress. To get an architectural overview and to learn about the current state of the project and its path forward read the [MapLibre GL Native Markdown Book](https://maplibre.org/maplibre-gl-native/docs/book/). See below for platform-specific documentation.
21
+ The documentation of MapLibre Native is a work in progress. To get an architectural overview and to learn about the current state of the project and its path forward read the [MapLibre Native Markdown Book](https://maplibre.org/maplibre-native/docs/book/). See below for platform-specific documentation.
20
22
 
21
23
  ## Platforms
22
24
 
23
- - [⭐️ Android](platform/android/README.md)
24
- - [⭐️ iOS](platform/ios/platform/ios/README.md)
25
+ - [⭐️ Android](platform/android/README.md)
26
+ - [⭐️ iOS](platform/ios/README.md)
25
27
  - [GLFW](platform/glfw)
26
28
  - [Linux](platform/linux/README.md)
27
29
  - [Node.js](platform/node/README.md)
28
30
  - [Qt](platform/qt/README.md)
29
31
  - [Windows](platform/windows/README.md)
30
- - [macOS](platform/ios/platform/macos/README.md)
32
+ - [macOS](platform/macos/README.md)
31
33
 
32
34
  Platforms with a ⭐️ are **MapLibre Core Projects** and have a substantial amount of financial resources allocated to them. Learn about the different [project tiers](https://github.com/maplibre/maplibre/blob/main/PROJECT_TIERS.md#project-tiers).
33
35
 
@@ -35,23 +37,24 @@ Platforms with a ⭐️ are **MapLibre Core Projects** and have a substantial am
35
37
 
36
38
  ![image-metal](https://user-images.githubusercontent.com/53421382/214308933-66cd4efb-b5a5-4de3-b4b4-7ed59045a1c3.png)
37
39
 
38
- MapLibre GL Native is being actively developed. Our big goal for 2023 is to modularize the OpenGL renderer and implement a Metal graphics backend (https://developer.apple.com/metal/). This will improve the performance and yield lower power consumption on iOS devices. At the same time, the Metal preparations will help us in the implementation of a Vulkan graphics backend.
40
+ MapLibre Native is being actively developed. Our big goal for 2023 is to modularize the OpenGL renderer and implement a Metal graphics backend (https://developer.apple.com/metal/). This will improve the performance and yield lower power consumption on iOS devices. At the same time, the Metal preparations will help us in the implementation of a Vulkan graphics backend.
39
41
 
40
42
  Your help in preparing the codebase for the latest graphics backends is more than welcome. Feel free to reach out if you are interested in joining the effort!
41
43
 
42
44
  - Check out the [news](https://maplibre.org/news/) on MapLibre's website.
43
- - See the [Design Proposals](https://github.com/louwers/maplibre-gl-native/tree/main/design-proposals) that have been accepted and are being worked on, the most recent ones being the [Rendering Modularization Design Proposal](design-proposals/2022-10-27-rendering-modularization.md) and the [Metal Port Design Proposal](design-proposals/2022-11-29-metal-port.md).
45
+ - See the [Design Proposals](https://github.com/maplibre/maplibre-native/tree/main/design-proposals) that have been accepted and are being worked on, the most recent ones being the [Rendering Modularization Design Proposal](design-proposals/2022-10-27-rendering-modularization.md) and the [Metal Port Design Proposal](design-proposals/2022-11-29-metal-port.md).
44
46
 
45
47
  ## Contributing
46
48
 
47
- To contribute to MapLibre GL Native, see [`CONTRIBUTING.md`](CONTRIBUTING.md) and (if applicable) the specific instructions for the platform you want to contribute to.
49
+ To contribute to MapLibre Native, see [`CONTRIBUTING.md`](CONTRIBUTING.md) and (if applicable) the specific instructions for the platform you want to contribute to.
48
50
 
49
51
  ### Getting Involved
50
52
 
51
- Join the `#maplibre-native` Slack channel at OSMUS. Get an invite at https://slack.openstreetmap.us/
53
+ Join the `#maplibre-native` Slack channel at OSMUS. Get an invite at https://slack.openstreetmap.us/
52
54
 
55
+ ### Bounties 💰
53
56
 
54
- ## Sponsors
57
+ Thanks to our sponsors, we are able to award bounties to developers making contributions toward certain [bounty directions](https://github.com/maplibre/maplibre/issues?q=is%3Aissue+is%3Aopen+label%3A%22bounty+direction%22). To get started doing bounties, refer to the [step-by-step bounties guide](https://maplibre.org/roadmap/step-by-step-bounties-guide/).
55
58
 
56
59
  We thank everyone who supported us financially in the past and special thanks to the people and organizations who support us with recurring donations!
57
60
 
@@ -59,16 +62,21 @@ Read more about the MapLibre Sponsorship Program at [https://maplibre.org/sponso
59
62
 
60
63
  Platinum:
61
64
 
62
- <img src="https://maplibre.org/img/aws-logo.svg" alt="Logo AWS" width="25%"/>
65
+ <a href="https://aws.com"><img src="https://maplibre.org/img/aws-logo.svg" alt="Logo AWS" width="25%"/></a>
66
+
67
+ Gold:
63
68
 
69
+ <a href="https://meta.com"><img src="https://maplibre.org/img/meta-logo.svg" alt="Logo Meta" width="25%"/></a>
64
70
 
65
71
  Silver:
66
72
 
67
- <img src="https://maplibre.org/img/meta-logo.svg" alt="Logo Meta" width="50%"/>
73
+ <a href="https://www.mierune.co.jp/?lang=en"><img src="https://maplibre.org/img/mierune-logo.svg" alt="Logo MIERUNE" width="25%"/></a>
74
+
75
+ <a href="https://komoot.com/"><img src="https://maplibre.org/img/komoot-logo.svg" alt="Logo komoot" width="25%"/></a>
68
76
 
69
- Stone:
77
+ <a href="https://www.jawg.io/"><img src="https://maplibre.org/img/jawgmaps-logo.svg" alt="Logo JawgMaps" width="25%"/></a>
70
78
 
71
- [MIERUNE Inc.](https://www.mierune.co.jp/?lang=en)
79
+ <a href="https://www.radar.com/"><img src="https://maplibre.org/img/radar-logo.svg" alt="Logo Radar" width="25%"/></a>
72
80
 
73
81
  Backers and Supporters:
74
82
 
@@ -76,4 +84,4 @@ Backers and Supporters:
76
84
 
77
85
  ## License
78
86
 
79
- **MapLibre GL Native** is licensed under the [BSD 2-Clause License](./LICENSE.md).
87
+ **MapLibre Native** is licensed under the [BSD 2-Clause License](./LICENSE.md).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@acalcutt/maplibre-gl-native-test",
3
- "version": "5.0.2-pre.7",
4
- "description": "Renders map tiles with Maplibre GL",
3
+ "version": "5.2.1-pre.10",
4
+ "description": "Renders map tiles with MapLibre Native",
5
5
  "keywords": [
6
6
  "maplibre",
7
7
  "gl"
@@ -17,13 +17,13 @@
17
17
  "types": "platform/node/index.d.ts",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "git+https://github.com/wifidb/maplibre-gl-native.git"
20
+ "url": "git+https://github.com/WifiDB/maplibre-native.git"
21
21
  },
22
22
  "license": "BSD-2-Clause",
23
23
  "dependencies": {
24
- "@acalcutt/node-pre-gyp": "^1.0.11",
24
+ "@acalcutt/node-pre-gyp": "^1.0.14",
25
25
  "@acalcutt/node-pre-gyp-github": "1.4.8",
26
- "minimatch": "^7.0.0",
26
+ "minimatch": "^7.2.0",
27
27
  "npm-run-all": "^4.0.2"
28
28
  },
29
29
  "devDependencies": {
@@ -31,6 +31,7 @@
31
31
  "@mapbox/mvt-fixtures": "3.10.0",
32
32
  "@octokit/plugin-retry": "^4.1.2",
33
33
  "@octokit/rest": "^19.0.7",
34
+ "argparse": "^2.0.1",
34
35
  "aws-sdk": "^2.1318.0",
35
36
  "csscolorparser": "~1.0.2",
36
37
  "d3-queue": "3.0.7",
@@ -47,7 +48,7 @@
47
48
  "pngjs": "^6.0.0",
48
49
  "pretty-bytes": "^6.1.0",
49
50
  "request": "^2.88.0",
50
- "semver": "^7.3.8",
51
+ "semver": "^7.5.2",
51
52
  "shuffle-seed": "1.1.6",
52
53
  "st": "3.0.0",
53
54
  "tape": "^5.6.3",
@@ -57,7 +58,7 @@
57
58
  "node": ">=6"
58
59
  },
59
60
  "scripts": {
60
- "install": "node-pre-gyp install --fallback-to-build=true",
61
+ "install": "node-pre-gyp install --fallback-to-build=false",
61
62
  "test": "tape platform/node/test/js/**/*.test.js",
62
63
  "test-memory": "node --expose-gc platform/node/test/memory.test.js",
63
64
  "test-expressions": "node -r esm platform/node/test/expression.test.js",
@@ -68,7 +69,7 @@
68
69
  "binary": {
69
70
  "module_name": "mbgl",
70
71
  "module_path": "./lib/{node_abi}",
71
- "host": "https://github.com/wifidb/maplibre-gl-native/releases/download/",
72
+ "host": "https://github.com/WifiDB/maplibre-native/releases/download/",
72
73
  "remote_path": "node-v{version}",
73
74
  "package_name": "{node_abi}-{platform}-{arch}-{configuration}.tar.gz"
74
75
  }
@@ -1,16 +1,17 @@
1
1
  # @maplibre/maplibre-gl-native
2
2
 
3
3
  [![Version](https://img.shields.io/npm/v/@maplibre/maplibre-gl-native?style=flat)](https://www.npmjs.com/package/@maplibre/maplibre-gl-native)
4
- [![node-ci](https://github.com/maplibre/maplibre-gl-native/actions/workflows/node-ci.yml/badge.svg)](https://github.com/maplibre/maplibre-gl-native/actions/workflows/node-ci.yml)
4
+ [![node-ci](https://github.com/maplibre/maplibre-native/actions/workflows/node-ci.yml/badge.svg)](https://github.com/maplibre/maplibre-native/actions/workflows/node-ci.yml)
5
5
 
6
6
  ## Installing
7
7
 
8
8
  Binaries are available and downloaded during install for the following platforms:
9
9
 
10
10
  - Operating systems:
11
- - Ubuntu 20.04 (amd64/arm64)
11
+ - Ubuntu 22.04 (amd64/arm64)
12
12
  - macOS 12 (amd64/arm64)
13
- - Node.js 14, 16, 18
13
+ - Windows (amd64)
14
+ - Node.js 16, 18, 20
14
15
 
15
16
  Run:
16
17
 
@@ -18,17 +19,48 @@ Run:
18
19
  npm install @maplibre/maplibre-gl-native
19
20
  ```
20
21
 
21
- Further platforms might work [with additional libraries installed](https://github.com/maplibre/maplibre-gl-native/tree/main/platform/linux#prerequisites).
22
+ Further platforms might work [with additional libraries installed](https://github.com/maplibre/maplibre-native/tree/main/platform/linux#prerequisites).
22
23
 
23
24
  ## Testing
24
25
 
25
26
  ```
26
27
  npm test
27
- npm run test-suite
28
28
  ```
29
29
 
30
30
  ## Rendering a map tile
31
31
 
32
+ The minimal example requires only the instantiation of the `mbgl.Map` object, loading a style and calling the `map.render` method:
33
+
34
+ ```js
35
+ var mbgl = require('@maplibre/maplibre-gl-native');
36
+ var sharp = require('sharp');
37
+
38
+ var map = new mbgl.Map();
39
+
40
+ map.load(require('./test/fixtures/style.json'));
41
+
42
+ map.render(function(err, buffer) {
43
+ if (err) throw err;
44
+
45
+ map.release();
46
+
47
+ var image = sharp(buffer, {
48
+ raw: {
49
+ width: 512,
50
+ height: 512,
51
+ channels: 4
52
+ }
53
+ });
54
+
55
+ // Convert raw image buffer to PNG
56
+ image.toFile('image.png', function(err) {
57
+ if (err) throw err;
58
+ });
59
+ });
60
+ ```
61
+
62
+ But you can customize the map providing an options object to `mbgl.Map` constructor and to `map.render` method:
63
+
32
64
  ```js
33
65
  var fs = require('fs');
34
66
  var path = require('path');
@@ -86,7 +118,7 @@ When you are finished using a map object, you can call `map.release()` to perman
86
118
 
87
119
  ## Implementing a file source
88
120
 
89
- When creating a `Map`, you must pass an options object (with a required `request` method and optional 'ratio' number) as the first parameter.
121
+ When creating a `Map`, you can optionally pass an options object (with an optional `request` method and optional `ratio` number) as the first parameter. The `request()` method handles a request for a resource. The `ratio` sets the scale at which the map will render tiles, such as `2.0` for rendering images for high pixel density displays:
90
122
 
91
123
  ```js
92
124
  var map = new mbgl.Map({
@@ -97,7 +129,7 @@ var map = new mbgl.Map({
97
129
  });
98
130
  ```
99
131
 
100
- The `request()` method handles a request for a resource. The `ratio` sets the scale at which the map will render tiles, such as `2.0` for rendering images for high pixel density displays. The `req` parameter has two properties:
132
+ If you omit the `request` method, the `map` object will use the default internal request handlers, which is ok for most cases. However, if you have specific needs, you can implement your own `request` handler. When a `request` method is provided, all `map` resources will be requested by calling the `request` method with two parameters, called `req` and `callback` respectively in this example. The `req` parameter has two properties:
101
133
 
102
134
  ```json
103
135
  {
@@ -106,7 +138,7 @@ The `request()` method handles a request for a resource. The `ratio` sets the sc
106
138
  }
107
139
  ```
108
140
 
109
- The `kind` is an enum and defined in [`mbgl.Resource`](https://github.com/maplibre/maplibre-gl-native/blob/main/include/mbgl/storage/resource.hpp):
141
+ The `kind` is an enum and defined in [`mbgl.Resource`](https://github.com/maplibre/maplibre-native/blob/main/include/mbgl/storage/resource.hpp):
110
142
 
111
143
  ```json
112
144
  {
@@ -122,7 +154,18 @@ The `kind` is an enum and defined in [`mbgl.Resource`](https://github.com/maplib
122
154
 
123
155
  The `kind` enum has no significance for anything but serves as a hint to your implemention as to what sort of resource to expect. E.g., your implementation could choose caching strategies based on the expected file type.
124
156
 
125
- The `request` implementation should pass uncompressed data to `callback`. If you are downloading assets from a source that applies gzip transport encoding, the implementation must decompress the results before passing them on.
157
+ The `callback` parameter is a function that must be called with two parameters: an error message (if there are no errors, then you must pass `null`), and a response object:
158
+
159
+ ```js
160
+ {
161
+ data: {data}, // required, must be a byte array, usually a Buffer object
162
+ modified: {modified}, // Date, optional
163
+ expires: {expires}, // Date, optional
164
+ etag: {etag} // string, optional
165
+ }
166
+ ```
167
+
168
+ If there is no data to be sent to the `callback` (empty data, or `no-content` respose), then it must be called without parameters. The `request` implementation should pass uncompressed data to `callback`. If you are downloading assets from a source that applies gzip transport encoding, the implementation must decompress the results before passing them on.
126
169
 
127
170
  A sample implementation that reads files from disk would look like the following:
128
171
 
@@ -172,6 +215,8 @@ var map = new mbgl.Map({
172
215
  response.data = body;
173
216
 
174
217
  callback(null, response);
218
+ } else if (res.statusCode == 204) {
219
+ callback();
175
220
  } else {
176
221
  callback(new Error(JSON.parse(body).message));
177
222
  }
@@ -184,7 +229,7 @@ Stylesheets are free to use any protocols, but your implementation of `request`
184
229
 
185
230
  ## Listening for log events
186
231
 
187
- The module imported with `require('maplibre-gl-native')` inherits from [`EventEmitter`](https://nodejs.org/api/events.html), and the `NodeLogObserver` will push log events to this. Log messages can have [`class`](https://github.com/maplibre/maplibre-gl-native/blob/node-v2.1.0/include/mbgl/platform/event.hpp#L43-L60), [`severity`](https://github.com/maplibre/maplibre-gl-native/blob/node-v2.1.0/include/mbgl/platform/event.hpp#L17-L23), `code` ([HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)), and `text` parameters.
232
+ The module imported with `require('maplibre-gl-native')` inherits from [`EventEmitter`](https://nodejs.org/api/events.html), and the `NodeLogObserver` will push log events to this. Log messages can have [`class`](https://github.com/maplibre/maplibre-native/blob/node-v2.1.0/include/mbgl/platform/event.hpp#L43-L60), [`severity`](https://github.com/maplibre/maplibre-native/blob/node-v2.1.0/include/mbgl/platform/event.hpp#L17-L23), `code` ([HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)), and `text` parameters.
188
233
 
189
234
  ```js
190
235
  var mbgl = require('@maplibre/maplibre-gl-native');
@@ -35,7 +35,7 @@ declare module '@maplibre/maplibre-gl-native' {
35
35
  /**
36
36
  * Will be used during a `Map.render` call to request all necessary map resources (tiles, fonts...)
37
37
  */
38
- request: (
38
+ request?: (
39
39
  request: { url: string; kind: ResourceKind },
40
40
  callback: (error?: Error, response?: RequestResponse) => void,
41
41
  ) => void;
@@ -60,6 +60,8 @@ declare module '@maplibre/maplibre-gl-native' {
60
60
  */
61
61
  type RenderOptions = {
62
62
  /**
63
+ * Zoom level
64
+ *
63
65
  * @default 0
64
66
  */
65
67
  zoom?: number;
@@ -109,21 +111,116 @@ declare module '@maplibre/maplibre-gl-native' {
109
111
  * A `Map` instance is used to render images from map views
110
112
  */
111
113
  class Map {
112
- constructor(mapOptions: MapOptions);
114
+ constructor(mapOptions?: MapOptions);
113
115
 
116
+ /**
117
+ * Load a style into a map
118
+ */
114
119
  load: (style: any) => void;
115
120
 
116
121
  /**
117
- * Render a specific map view to an image with previously loaded map styles
122
+ * Render a specific map view to an image with previously loaded map styles with render options.
118
123
  */
119
- render: (
120
- renderOptions: RenderOptions,
121
- callback: (...args: [error: Error, buffer: undefined] | [error: undefined, buffer: Uint8Array]) => void,
122
- ) => void;
124
+ render(renderOptions: RenderOptions, callback: (...args: [error: Error, buffer: undefined] | [error: undefined, buffer: Uint8Array]) => void): void;
125
+
126
+ /**
127
+ * Render a specific map view to an image with previously loaded map styles without render options.
128
+ */
129
+ render(callback: (...args: [error: Error, buffer: undefined] | [error: undefined, buffer: Uint8Array]) => void): void;
123
130
 
124
131
  /**
125
132
  * Call to permanently dispose the internal map resources, instance can't be used for further render calls
126
133
  */
127
134
  release: () => void;
135
+
136
+ /**
137
+ * Add source to map's style
138
+ */
139
+ addSource: (sourceId: string, source: object) => void;
140
+
141
+ /**
142
+ * Remove source from map's style
143
+ */
144
+ removeSource: (sourceId: string) => void;
145
+
146
+ /**
147
+ * Add layer to map's style
148
+ */
149
+ addLayer: (layer: object, beforeId?: string) => void;
150
+
151
+ /**
152
+ * Remove layer from map's style
153
+ */
154
+ removeLayer: (layerId: string) => void;
155
+
156
+ /**
157
+ * Add image to map's style
158
+ */
159
+ addImage: (imageId: string, image: any) => void;
160
+
161
+ /**
162
+ * Remove image from map's style
163
+ */
164
+ removeImage: (imageId: string) => void;
165
+
166
+ /**
167
+ * Set the extent of the zoom for a specified layer
168
+ */
169
+ setLayerZoomRange: (layerId: string, minZoom: number, maxZoom: number) => void;
170
+
171
+ /**
172
+ * Set the value for a layer's property
173
+ */
174
+ setLayoutProperty: (layerId: string, name: string, value: string) => void;
175
+
176
+ /**
177
+ * Set filter for specified style layer
178
+ */
179
+ setFilter: (layerId: string, filter: [] | null | undefined) => void;
180
+
181
+ /**
182
+ * Set size of the tile
183
+ */
184
+ setSize: (size: [number, number]) => void;
185
+
186
+ /**
187
+ * Set the center of the map
188
+ */
189
+ setCenter: (center: [number, number]) => void;
190
+
191
+ /**
192
+ * Set zoom of the map
193
+ */
194
+ setZoom: (zoom: number) => void;
195
+
196
+ /**
197
+ * Set bearing (rotation) of map
198
+ */
199
+ setBearing: (bearing: number) => void;
200
+
201
+ /**
202
+ * Set pitch (tilt angle) of map
203
+ */
204
+ setPitch: (pitch: number) => void;
205
+
206
+ /**
207
+ * Set light value of map
208
+ */
209
+ setLight: (light: any) => void;
210
+
211
+ /**
212
+ * Set axonometric view of map
213
+ */
214
+ setAxonometric: (state: boolean) => void;
215
+
216
+ /**
217
+ * Set X skew of map
218
+ */
219
+ setXSkew: (x: number) => void;
220
+
221
+ /**
222
+ * Set Y skew of map
223
+ */
224
+ setYSkew: (y: number) => void;
128
225
  }
129
226
  }
@@ -6,43 +6,49 @@ var mbgl = require('../../lib/node-v' + process.versions.modules + '/mbgl');
6
6
  var constructor = mbgl.Map.prototype.constructor;
7
7
 
8
8
  var Map = function(options) {
9
- if (!(options instanceof Object)) {
9
+ if (options && !(options instanceof Object)) {
10
10
  throw TypeError("Requires an options object as first argument");
11
11
  }
12
12
 
13
- if (!options.hasOwnProperty('request') || !(options.request instanceof Function)) {
14
- throw TypeError("Options object must have a 'request' method");
13
+ if (options && options.hasOwnProperty('request') && !(options.request instanceof Function)) {
14
+ throw TypeError("Options object 'request' property must be a function");
15
15
  }
16
16
 
17
- var request = options.request;
18
-
19
- return new constructor(Object.assign(options, {
20
- request: function(req) {
21
- // Protect against `request` implementations that call the callback synchronously,
22
- // call it multiple times, or throw exceptions.
23
- // http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
24
-
25
- var responded = false;
26
- var callback = function() {
27
- var args = arguments;
28
- if (!responded) {
29
- responded = true;
30
- process.nextTick(function() {
31
- req.respond.apply(req, args);
32
- });
33
- } else {
34
- console.warn('request function responded multiple times; it should call the callback only once');
17
+ if (options && options.request) {
18
+ var request = options.request;
19
+
20
+ return new constructor(Object.assign(options, {
21
+ request: function(req) {
22
+ // Protect against `request` implementations that call the callback synchronously,
23
+ // call it multiple times, or throw exceptions.
24
+ // http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
25
+
26
+ var responded = false;
27
+ var callback = function() {
28
+ var args = arguments;
29
+ if (!responded) {
30
+ responded = true;
31
+ process.nextTick(function() {
32
+ req.respond.apply(req, args);
33
+ });
34
+ } else {
35
+ console.warn('request function responded multiple times; it should call the callback only once');
36
+ }
37
+ };
38
+
39
+ try {
40
+ request(req, callback);
41
+ } catch (e) {
42
+ console.warn('request function threw an exception; it should call the callback with an error instead');
43
+ callback(e);
35
44
  }
36
- };
37
-
38
- try {
39
- request(req, callback);
40
- } catch (e) {
41
- console.warn('request function threw an exception; it should call the callback with an error instead');
42
- callback(e);
43
45
  }
44
- }
45
- }));
46
+ }));
47
+ } else if (options) {
48
+ return new constructor(options);
49
+ } else {
50
+ return new constructor();
51
+ }
46
52
  };
47
53
 
48
54
  Map.prototype = mbgl.Map.prototype;