<commit_before>'use strict';

var isFunction = require('lodash/isFunction');
var extend = require('lodash/extend');
var each = require('lodash/each');
var uuid = require('../util/uuid');
var Document = require('./Document');
var DocumentChange = require('./DocumentChange');
var IncrementalData = require('./data/IncrementalData');
var DocumentNodeFactory = require('./DocumentNodeFactory');

var __id__ = 0;

/**
  A {@link model/Document} instance that is used during transaction.

  During editing a TransactionDocument is kept up-to-date with the real one.
  Whenever a transaction is started on the document, a TransactionDocument is used to
  record changes, which are applied en-bloc when the transaction is saved.

  @class
  @extends model/AbstractDocument
  @example

  @param {model/Document} document a document instance

  To start a transaction run

  ```
  doc.transaction(function(tx) {
    // use tx to record changes
  });
  ```
*/
function TransactionDocument(document, session) {
  this.__id__ = "TX_"+__id__++;

  this.schema = document.schema;
  this.nodeFactory = new DocumentNodeFactory(this);
  this.data = new IncrementalData(this.schema, {
    nodeFactory: this.nodeFactory
  });

  this.document = document;
  this.session = session;

  // ops recorded since transaction start
  this.ops = [];
  // app information state information used to recover the state before the transaction
  // when calling undo
  this.before = {};
  // HACK: copying all indexes
  each(document.data.indexes, function(index, name) {
    this.data.addIndex(name, index.clone());
  }.bind(this));

  this.loadSeed(document.toJSON());
}

TransactionDocument.Prototype = function() {

  this.reset = function() {
    this.ops = [];
    this.before = {};
  };

  this.create = function(nodeData) {
    if (!nodeData.id) {
      nodeData.id = uuid(nodeData.type);
    }
    var op = this.data.create(nodeData);
    if (!op) return;
    this.ops.push(op);
    // TODO: incremental graph returns op not the node,
    // so probably here we should too?
    return this.data.get(nodeData.id);
  };

  this.delete = function(nodeId) {
    var op = this.data.delete(nodeId);
    if (!op) return;
    this.ops.push(op);
    return op;
  };<commit_msg>Early failing on node creation if no type is provided.<commit_after>'use strict';

var isFunction = require('lodash/isFunction');
var extend = require('lodash/extend');
var each = require('lodash/each');
var uuid = require('../util/uuid');
var Document = require('./Document');
var DocumentChange = require('./DocumentChange');
var IncrementalData = require('./data/IncrementalData');
var DocumentNodeFactory = require('./DocumentNodeFactory');

var __id__ = 0;

/**
  A {@link model/Document} instance that is used during transaction.

  During editing a TransactionDocument is kept up-to-date with the real one.
  Whenever a transaction is started on the document, a TransactionDocument is used to
  record changes, which are applied en-bloc when the transaction is saved.

  @class
  @extends model/AbstractDocument
  @example

  @param {model/Document} document a document instance

  To start a transaction run

  ```
  doc.transaction(function(tx) {
    // use tx to record changes
  });
  ```
*/
function TransactionDocument(document, session) {
  this.__id__ = "TX_"+__id__++;

  this.schema = document.schema;
  this.nodeFactory = new DocumentNodeFactory(this);
  this.data = new IncrementalData(this.schema, {
    nodeFactory: this.nodeFactory
  });

  this.document = document;
  this.session = session;

  // ops recorded since transaction start
  this.ops = [];
  // app information state information used to recover the state before the transaction
  // when calling undo
  this.before = {};
  // HACK: copying all indexes
  each(document.data.indexes, function(index, name) {
    this.data.addIndex(name, index.clone());
  }.bind(this));

  this.loadSeed(document.toJSON());
}

TransactionDocument.Prototype = function() {

  this.reset = function() {
    this.ops = [];
    this.before = {};
  };

  this.create = function(nodeData) {
    if (!nodeData.id) {
      nodeData.id = uuid(nodeData.type);
    }
    if (!nodeData.type) {
      throw new Error('No node type provided');
    }
    var op = this.data.create(nodeData);
    if (!op) return;
    this.ops.push(op);
    // TODO: incremental graph returns op not the node,
    // so probably here we should too?
    return this.data.get(nodeData.id);
  };

  this.delete = function(nodeId) {
    var op = this.data.delete(nodeId);
    if (!op) return;
    this.ops.push(op);
    return op;
  };
{'fraction_non_alphanumeric': 0.1298024744953332, 'fraction_numerical': 0.0004341219882787063, 'mean_word_length': 3.544378698224852, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7363633', 'n_tokens_mistral': 1383, 'n_tokens_neox': 1339, 'n_words': 401}