adds integrations with bookish-server, the books API and the google books API, adds functionality for library, searching for books, and displaying renters registered in the system

This commit is contained in:
David Lick
2020-05-28 22:08:27 -04:00
parent 888dec3402
commit a06b4d70ab
337 changed files with 17276 additions and 91 deletions
+124
View File
@@ -0,0 +1,124 @@
import { getBatch } from './batch'; // encapsulates the subscription logic for connecting a component to the redux store, as
// well as nesting subscriptions of descendant components, so that we can ensure the
// ancestor components re-render before descendants
var nullListeners = {
notify: function notify() {}
};
function createListenerCollection() {
var batch = getBatch();
var first = null;
var last = null;
return {
clear: function clear() {
first = null;
last = null;
},
notify: function notify() {
batch(function () {
var listener = first;
while (listener) {
listener.callback();
listener = listener.next;
}
});
},
get: function get() {
var listeners = [];
var listener = first;
while (listener) {
listeners.push(listener);
listener = listener.next;
}
return listeners;
},
subscribe: function subscribe(callback) {
var isSubscribed = true;
var listener = last = {
callback: callback,
next: null,
prev: last
};
if (listener.prev) {
listener.prev.next = listener;
} else {
first = listener;
}
return function unsubscribe() {
if (!isSubscribed || first === null) return;
isSubscribed = false;
if (listener.next) {
listener.next.prev = listener.prev;
} else {
last = listener.prev;
}
if (listener.prev) {
listener.prev.next = listener.next;
} else {
first = listener.next;
}
};
}
};
}
var Subscription =
/*#__PURE__*/
function () {
function Subscription(store, parentSub) {
this.store = store;
this.parentSub = parentSub;
this.unsubscribe = null;
this.listeners = nullListeners;
this.handleChangeWrapper = this.handleChangeWrapper.bind(this);
}
var _proto = Subscription.prototype;
_proto.addNestedSub = function addNestedSub(listener) {
this.trySubscribe();
return this.listeners.subscribe(listener);
};
_proto.notifyNestedSubs = function notifyNestedSubs() {
this.listeners.notify();
};
_proto.handleChangeWrapper = function handleChangeWrapper() {
if (this.onStateChange) {
this.onStateChange();
}
};
_proto.isSubscribed = function isSubscribed() {
return Boolean(this.unsubscribe);
};
_proto.trySubscribe = function trySubscribe() {
if (!this.unsubscribe) {
this.unsubscribe = this.parentSub ? this.parentSub.addNestedSub(this.handleChangeWrapper) : this.store.subscribe(this.handleChangeWrapper);
this.listeners = createListenerCollection();
}
};
_proto.tryUnsubscribe = function tryUnsubscribe() {
if (this.unsubscribe) {
this.unsubscribe();
this.unsubscribe = null;
this.listeners.clear();
this.listeners = nullListeners;
}
};
return Subscription;
}();
export { Subscription as default };
+14
View File
@@ -0,0 +1,14 @@
// Default to a dummy "batch" implementation that just runs the callback
function defaultNoopBatch(callback) {
callback();
}
var batch = defaultNoopBatch; // Allow injecting another batching function later
export var setBatch = function setBatch(newBatch) {
return batch = newBatch;
}; // Supply a getter just to skip dealing with ESM bindings
export var getBatch = function getBatch() {
return batch;
};
+16
View File
@@ -0,0 +1,16 @@
/**
* @param {any} obj The object to inspect.
* @returns {boolean} True if the argument appears to be a plain object.
*/
export default function isPlainObject(obj) {
if (typeof obj !== 'object' || obj === null) return false;
var proto = Object.getPrototypeOf(obj);
if (proto === null) return true;
var baseProto = proto;
while (Object.getPrototypeOf(baseProto) !== null) {
baseProto = Object.getPrototypeOf(baseProto);
}
return proto === baseProto;
}
+2
View File
@@ -0,0 +1,2 @@
/* eslint-disable import/no-unresolved */
export { unstable_batchedUpdates } from 'react-dom';
+3
View File
@@ -0,0 +1,3 @@
/* eslint-disable import/no-unresolved */
import { unstable_batchedUpdates } from 'react-native';
export { unstable_batchedUpdates };
+27
View File
@@ -0,0 +1,27 @@
function is(x, y) {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
return x !== x && y !== y;
}
}
export default function shallowEqual(objA, objB) {
if (is(objA, objB)) return true;
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
return false;
}
var keysA = Object.keys(objA);
var keysB = Object.keys(objB);
if (keysA.length !== keysB.length) return false;
for (var i = 0; i < keysA.length; i++) {
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}
+10
View File
@@ -0,0 +1,10 @@
import { useEffect, useLayoutEffect } from 'react'; // React currently throws a warning when using useLayoutEffect on the server.
// To get around it, we can conditionally useEffect on the server (no-op) and
// useLayoutEffect in the browser. We need useLayoutEffect to ensure the store
// subscription callback always has the selector from the latest render commit
// available, otherwise a store update may happen between render and the effect,
// which may cause missed updates; we also must ensure the store subscription
// is created synchronously, otherwise a store update may occur before the
// subscription is created and an inconsistent state may be observed
export var useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? useLayoutEffect : useEffect;
@@ -0,0 +1,3 @@
import { useLayoutEffect } from 'react'; // Under React Native, we know that we always want to use useLayoutEffect
export var useIsomorphicLayoutEffect = useLayoutEffect;
+7
View File
@@ -0,0 +1,7 @@
import isPlainObject from './isPlainObject';
import warning from './warning';
export default function verifyPlainObject(value, displayName, methodName) {
if (!isPlainObject(value)) {
warning(methodName + "() in " + displayName + " must return a plain object. Instead received " + value + ".");
}
}
+24
View File
@@ -0,0 +1,24 @@
/**
* Prints a warning in the console if it exists.
*
* @param {String} message The warning message.
* @returns {void}
*/
export default function warning(message) {
/* eslint-disable no-console */
if (typeof console !== 'undefined' && typeof console.error === 'function') {
console.error(message);
}
/* eslint-enable no-console */
try {
// This error was thrown as a convenience so that if you enable
// "break on all exceptions" in your console,
// it would pause the execution at this line.
throw new Error(message);
/* eslint-disable no-empty */
} catch (e) {}
/* eslint-enable no-empty */
}
+6
View File
@@ -0,0 +1,6 @@
import { bindActionCreators } from 'redux';
export default function wrapActionCreators(actionCreators) {
return function (dispatch) {
return bindActionCreators(actionCreators, dispatch);
};
}